diff --git a/3rdparty/ffmpeg/ffmpeg.cmake b/3rdparty/ffmpeg/ffmpeg.cmake index 3cd5e1be94b1..764e4b19d830 100644 --- a/3rdparty/ffmpeg/ffmpeg.cmake +++ b/3rdparty/ffmpeg/ffmpeg.cmake @@ -1,9 +1,9 @@ -# Binaries branch name: ffmpeg/master_20210303 -# Binaries were created for OpenCV: 7ac6abe02a33bef445a5b77214ad31964e2c5cc1 -ocv_update(FFMPEG_BINARIES_COMMIT "629590c3ba09fb0c8eaa9ab858ff13d3a84ca1aa") -ocv_update(FFMPEG_FILE_HASH_BIN32 "638065d5a0dab8a828879942375dcac4") -ocv_update(FFMPEG_FILE_HASH_BIN64 "7f10ae2e6a080ba3714f7a38ee03ae15") -ocv_update(FFMPEG_FILE_HASH_CMAKE "f8e65dbe4a3b4eedc0d2997e07c3f3fd") +# Binaries branch name: ffmpeg/master_20210608 +# Binaries were created for OpenCV: eaa9228a4fdfb9c2465aea65a50ce2d16b55dce0 +ocv_update(FFMPEG_BINARIES_COMMIT "213fcd5d4897319a83207406036c4a5957fba010") +ocv_update(FFMPEG_FILE_HASH_BIN32 "bab661341c30862fa88627130219c0a5") +ocv_update(FFMPEG_FILE_HASH_BIN64 "ac99f9767a83103c31709628af685924") +ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7") function(download_win_ffmpeg script_var) set(${script_var} "" PARENT_SCOPE) diff --git a/3rdparty/libjpeg-turbo/CMakeLists.txt b/3rdparty/libjpeg-turbo/CMakeLists.txt index 901669a4a8c3..3c7f29b08e95 100644 --- a/3rdparty/libjpeg-turbo/CMakeLists.txt +++ b/3rdparty/libjpeg-turbo/CMakeLists.txt @@ -3,10 +3,10 @@ project(${JPEG_LIBRARY} C) ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter -Wsign-compare -Wshorten-64-to-32 -Wimplicit-fallthrough) set(VERSION_MAJOR 2) -set(VERSION_MINOR 0) -set(VERSION_REVISION 6) +set(VERSION_MINOR 1) +set(VERSION_REVISION 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}) -set(LIBJPEG_TURBO_VERSION_NUMBER 2000006) +set(LIBJPEG_TURBO_VERSION_NUMBER 2001000) string(TIMESTAMP BUILD "opencv-${OPENCV_VERSION}-libjpeg-turbo") if(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -46,7 +46,6 @@ if(UNIX) ocv_update(HAVE_UNSIGNED_SHORT 1) # undef INCOMPLETE_TYPES_BROKEN ocv_update(RIGHT_SHIFT_IS_UNSIGNED 0) - ocv_update(__CHAR_UNSIGNED__ 0) endif() diff --git a/3rdparty/libjpeg-turbo/LICENSE.md b/3rdparty/libjpeg-turbo/LICENSE.md index 99c9aadcc47c..a1cdad52faf4 100644 --- a/3rdparty/libjpeg-turbo/LICENSE.md +++ b/3rdparty/libjpeg-turbo/LICENSE.md @@ -91,7 +91,7 @@ best of our understanding. The Modified (3-clause) BSD License =================================== -Copyright (C)2009-2020 D. R. Commander. All Rights Reserved. +Copyright (C)2009-2021 D. R. Commander. All Rights Reserved.
Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. Redistribution and use in source and binary forms, with or without diff --git a/3rdparty/libjpeg-turbo/README.ijg b/3rdparty/libjpeg-turbo/README.ijg index d681cf1273d4..9453c195010f 100644 --- a/3rdparty/libjpeg-turbo/README.ijg +++ b/3rdparty/libjpeg-turbo/README.ijg @@ -128,7 +128,7 @@ with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided "AS IS", and you, its user, assume the entire risk as to its quality and accuracy. -This software is copyright (C) 1991-2016, Thomas G. Lane, Guido Vollbeding. +This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. All Rights Reserved except as specified below. Permission is hereby granted to use, copy, modify, and distribute this @@ -159,19 +159,6 @@ commercial products, provided that all warranty or liability claims are assumed by the product vendor. -The IJG distribution formerly included code to read and write GIF files. -To avoid entanglement with the Unisys LZW patent (now expired), GIF reading -support has been removed altogether, and the GIF writer has been simplified -to produce "uncompressed GIFs". This technique does not use the LZW -algorithm; the resulting GIF files are larger than usual, but are readable -by all standard GIF decoders. - -We are required to state that - "The Graphics Interchange Format(c) is the Copyright property of - CompuServe Incorporated. GIF(sm) is a Service Mark property of - CompuServe Incorporated." - - REFERENCES ========== diff --git a/3rdparty/libjpeg-turbo/README.md b/3rdparty/libjpeg-turbo/README.md index 90a4a43ee1de..01e391ea7c08 100644 --- a/3rdparty/libjpeg-turbo/README.md +++ b/3rdparty/libjpeg-turbo/README.md @@ -3,7 +3,7 @@ Background libjpeg-turbo is a JPEG image codec that uses SIMD instructions to accelerate baseline JPEG compression and decompression on x86, x86-64, Arm, PowerPC, and -MIPS systems, as well as progressive JPEG compression on x86 and x86-64 +MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm systems. On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg, all else being equal. On other types of systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by virtue of its highly-optimized diff --git a/3rdparty/libjpeg-turbo/jconfig.h.in b/3rdparty/libjpeg-turbo/jconfig.h.in index 18a69a48142a..d4284d97b812 100644 --- a/3rdparty/libjpeg-turbo/jconfig.h.in +++ b/3rdparty/libjpeg-turbo/jconfig.h.in @@ -61,11 +61,6 @@ unsigned. */ #cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1 -/* Define to 1 if type `char' is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ - #cmakedefine __CHAR_UNSIGNED__ 1 -#endif - /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/3rdparty/libjpeg-turbo/jconfig.h.win.in b/3rdparty/libjpeg-turbo/jconfig.h.win.in index 6db0b345b2df..13cceef01d13 100644 --- a/3rdparty/libjpeg-turbo/jconfig.h.win.in +++ b/3rdparty/libjpeg-turbo/jconfig.h.win.in @@ -18,7 +18,6 @@ #define HAVE_UNSIGNED_SHORT #undef INCOMPLETE_TYPES_BROKEN #undef RIGHT_SHIFT_IS_UNSIGNED -#undef __CHAR_UNSIGNED__ /* Define "boolean" as unsigned char, not int, per Windows custom */ #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ diff --git a/3rdparty/libjpeg-turbo/src/jccolext.c b/3rdparty/libjpeg-turbo/src/jccolext.c index 19c955c9d6af..303b322ce674 100644 --- a/3rdparty/libjpeg-turbo/src/jccolext.c +++ b/3rdparty/libjpeg-turbo/src/jccolext.c @@ -48,9 +48,9 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf, outptr2 = output_buf[2][output_row]; output_row++; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); + r = inptr[RGB_RED]; + g = inptr[RGB_GREEN]; + b = inptr[RGB_BLUE]; inptr += RGB_PIXELSIZE; /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations * must be too; we do not need an explicit range-limiting operation. @@ -100,9 +100,9 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf, outptr = output_buf[0][output_row]; output_row++; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); + r = inptr[RGB_RED]; + g = inptr[RGB_GREEN]; + b = inptr[RGB_BLUE]; inptr += RGB_PIXELSIZE; /* Y */ outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] + @@ -135,9 +135,9 @@ rgb_rgb_convert_internal(j_compress_ptr cinfo, JSAMPARRAY input_buf, outptr2 = output_buf[2][output_row]; output_row++; for (col = 0; col < num_cols; col++) { - outptr0[col] = GETJSAMPLE(inptr[RGB_RED]); - outptr1[col] = GETJSAMPLE(inptr[RGB_GREEN]); - outptr2[col] = GETJSAMPLE(inptr[RGB_BLUE]); + outptr0[col] = inptr[RGB_RED]; + outptr1[col] = inptr[RGB_GREEN]; + outptr2[col] = inptr[RGB_BLUE]; inptr += RGB_PIXELSIZE; } } diff --git a/3rdparty/libjpeg-turbo/src/jccolor.c b/3rdparty/libjpeg-turbo/src/jccolor.c index 036f6016d18c..bdc563c723ca 100644 --- a/3rdparty/libjpeg-turbo/src/jccolor.c +++ b/3rdparty/libjpeg-turbo/src/jccolor.c @@ -392,11 +392,11 @@ cmyk_ycck_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, outptr3 = output_buf[3][output_row]; output_row++; for (col = 0; col < num_cols; col++) { - r = MAXJSAMPLE - GETJSAMPLE(inptr[0]); - g = MAXJSAMPLE - GETJSAMPLE(inptr[1]); - b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); + r = MAXJSAMPLE - inptr[0]; + g = MAXJSAMPLE - inptr[1]; + b = MAXJSAMPLE - inptr[2]; /* K passes through as-is */ - outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ + outptr3[col] = inptr[3]; inptr += 4; /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations * must be too; we do not need an explicit range-limiting operation. @@ -438,7 +438,7 @@ grayscale_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, outptr = output_buf[0][output_row]; output_row++; for (col = 0; col < num_cols; col++) { - outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ + outptr[col] = inptr[0]; inptr += instride; } } @@ -497,7 +497,7 @@ null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, inptr = *input_buf; outptr = output_buf[ci][output_row]; for (col = 0; col < num_cols; col++) { - outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ + outptr[col] = inptr[ci]; inptr += nc; } } diff --git a/3rdparty/libjpeg-turbo/src/jcdctmgr.c b/3rdparty/libjpeg-turbo/src/jcdctmgr.c index c04058e6cec9..7dae17a6e149 100644 --- a/3rdparty/libjpeg-turbo/src/jcdctmgr.c +++ b/3rdparty/libjpeg-turbo/src/jcdctmgr.c @@ -381,19 +381,19 @@ convsamp(JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM *workspace) elemptr = sample_data[elemr] + start_col; #if DCTSIZE == 8 /* unroll the inner loop */ - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; #else { register int elemc; for (elemc = DCTSIZE; elemc > 0; elemc--) - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE; } #endif } @@ -533,20 +533,19 @@ convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col, for (elemr = 0; elemr < DCTSIZE; elemr++) { elemptr = sample_data[elemr] + start_col; #if DCTSIZE == 8 /* unroll the inner loop */ - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); #else { register int elemc; for (elemc = DCTSIZE; elemc > 0; elemc--) - *workspaceptr++ = (FAST_FLOAT) - (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE); } #endif } diff --git a/3rdparty/libjpeg-turbo/src/jchuff.c b/3rdparty/libjpeg-turbo/src/jchuff.c index db85ce114f8b..2bce767ebd70 100644 --- a/3rdparty/libjpeg-turbo/src/jchuff.c +++ b/3rdparty/libjpeg-turbo/src/jchuff.c @@ -4,8 +4,10 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-1997, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2009-2011, 2014-2016, 2018-2019, D. R. Commander. + * Copyright (C) 2009-2011, 2014-2016, 2018-2021, D. R. Commander. * Copyright (C) 2015, Matthieu Darbois. + * Copyright (C) 2018, Matthias Räncker. + * Copyright (C) 2020, Arm Limited. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -42,15 +44,19 @@ * flags (this defines __thumb__). */ -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__)) +#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \ + defined(_M_ARM64) #if !defined(__thumb__) || defined(__thumb2__) #define USE_CLZ_INTRINSIC #endif #endif #ifdef USE_CLZ_INTRINSIC +#if defined(_MSC_VER) && !defined(__clang__) +#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) +#else #define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) +#endif #define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) #else #include "jpeg_nbits_table.h" @@ -65,31 +71,42 @@ * but must not be updated permanently until we complete the MCU. */ -typedef struct { - size_t put_buffer; /* current bit-accumulation buffer */ - int put_bits; /* # of bits now in it */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; +#if defined(__x86_64__) && defined(__ILP32__) +typedef unsigned long long bit_buf_type; +#else +typedef size_t bit_buf_type; +#endif -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. +/* NOTE: The more optimal Huffman encoding algorithm is only used by the + * intrinsics implementation of the Arm Neon SIMD extensions, which is why we + * retain the old Huffman encoder behavior when using the GAS implementation. */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest, src) ((dest) = (src)) +#if defined(WITH_SIMD) && !(defined(__arm__) || defined(__aarch64__) || \ + defined(_M_ARM) || defined(_M_ARM64)) +typedef unsigned long long simd_bit_buf_type; #else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest, src) \ - ((dest).put_buffer = (src).put_buffer, \ - (dest).put_bits = (src).put_bits, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) +typedef bit_buf_type simd_bit_buf_type; #endif + +#if (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 8) || defined(_WIN64) || \ + (defined(__x86_64__) && defined(__ILP32__)) +#define BIT_BUF_SIZE 64 +#elif (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 4) || defined(_WIN32) +#define BIT_BUF_SIZE 32 +#else +#error Cannot determine word size #endif +#define SIMD_BIT_BUF_SIZE (sizeof(simd_bit_buf_type) * 8) +typedef struct { + union { + bit_buf_type c; + simd_bit_buf_type simd; + } put_buffer; /* current bit accumulation buffer */ + int free_bits; /* # of bits available in it */ + /* (Neon GAS: # of bits now in it) */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; typedef struct { struct jpeg_entropy_encoder pub; /* public fields */ @@ -123,6 +140,7 @@ typedef struct { size_t free_in_buffer; /* # of byte spaces remaining in buffer */ savable_state cur; /* Current bit buffer & DC state */ j_compress_ptr cinfo; /* dump_buffer needs access to this */ + int simd; } working_state; @@ -201,8 +219,17 @@ start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics) } /* Initialize bit buffer to empty */ - entropy->saved.put_buffer = 0; - entropy->saved.put_bits = 0; + if (entropy->simd) { + entropy->saved.put_buffer.simd = 0; +#if defined(__aarch64__) && !defined(NEON_INTRINSICS) + entropy->saved.free_bits = 0; +#else + entropy->saved.free_bits = SIMD_BIT_BUF_SIZE; +#endif + } else { + entropy->saved.put_buffer.c = 0; + entropy->saved.free_bits = BIT_BUF_SIZE; + } /* Initialize restart stuff */ entropy->restarts_to_go = cinfo->restart_interval; @@ -287,6 +314,7 @@ jpeg_make_c_derived_tbl(j_compress_ptr cinfo, boolean isDC, int tblno, * this lets us detect duplicate VAL entries here, and later * allows emit_bits to detect any attempt to emit such symbols. */ + MEMZERO(dtbl->ehufco, sizeof(dtbl->ehufco)); MEMZERO(dtbl->ehufsi, sizeof(dtbl->ehufsi)); /* This is also a convenient place to check for out-of-range @@ -334,94 +362,94 @@ dump_buffer(working_state *state) /* Outputting bits to the file */ -/* These macros perform the same task as the emit_bits() function in the - * original libjpeg code. In addition to reducing overhead by explicitly - * inlining the code, additional performance is achieved by taking into - * account the size of the bit buffer and waiting until it is almost full - * before emptying it. This mostly benefits 64-bit platforms, since 6 - * bytes can be stored in a 64-bit bit buffer before it has to be emptied. +/* Output byte b and, speculatively, an additional 0 byte. 0xFF must be + * encoded as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the + * byte is 0xFF. Otherwise, the output buffer pointer is advanced by 1, and + * the speculative 0 byte will be overwritten by the next byte. */ - -#define EMIT_BYTE() { \ - JOCTET c; \ - put_bits -= 8; \ - c = (JOCTET)GETJOCTET(put_buffer >> put_bits); \ - *buffer++ = c; \ - if (c == 0xFF) /* need to stuff a zero byte? */ \ - *buffer++ = 0; \ +#define EMIT_BYTE(b) { \ + buffer[0] = (JOCTET)(b); \ + buffer[1] = 0; \ + buffer -= -2 + ((JOCTET)(b) < 0xFF); \ } -#define PUT_BITS(code, size) { \ - put_bits += size; \ - put_buffer = (put_buffer << size) | code; \ -} - -#if SIZEOF_SIZE_T != 8 && !defined(_WIN64) - -#define CHECKBUF15() { \ - if (put_bits > 15) { \ - EMIT_BYTE() \ - EMIT_BYTE() \ +/* Output the entire bit buffer. If there are no 0xFF bytes in it, then write + * directly to the output buffer. Otherwise, use the EMIT_BYTE() macro to + * encode 0xFF as 0xFF 0x00. + */ +#if BIT_BUF_SIZE == 64 + +#define FLUSH() { \ + if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \ + EMIT_BYTE(put_buffer >> 56) \ + EMIT_BYTE(put_buffer >> 48) \ + EMIT_BYTE(put_buffer >> 40) \ + EMIT_BYTE(put_buffer >> 32) \ + EMIT_BYTE(put_buffer >> 24) \ + EMIT_BYTE(put_buffer >> 16) \ + EMIT_BYTE(put_buffer >> 8) \ + EMIT_BYTE(put_buffer ) \ + } else { \ + buffer[0] = (JOCTET)(put_buffer >> 56); \ + buffer[1] = (JOCTET)(put_buffer >> 48); \ + buffer[2] = (JOCTET)(put_buffer >> 40); \ + buffer[3] = (JOCTET)(put_buffer >> 32); \ + buffer[4] = (JOCTET)(put_buffer >> 24); \ + buffer[5] = (JOCTET)(put_buffer >> 16); \ + buffer[6] = (JOCTET)(put_buffer >> 8); \ + buffer[7] = (JOCTET)(put_buffer); \ + buffer += 8; \ } \ } -#endif - -#define CHECKBUF31() { \ - if (put_bits > 31) { \ - EMIT_BYTE() \ - EMIT_BYTE() \ - EMIT_BYTE() \ - EMIT_BYTE() \ - } \ -} +#else -#define CHECKBUF47() { \ - if (put_bits > 47) { \ - EMIT_BYTE() \ - EMIT_BYTE() \ - EMIT_BYTE() \ - EMIT_BYTE() \ - EMIT_BYTE() \ - EMIT_BYTE() \ +#define FLUSH() { \ + if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \ + EMIT_BYTE(put_buffer >> 24) \ + EMIT_BYTE(put_buffer >> 16) \ + EMIT_BYTE(put_buffer >> 8) \ + EMIT_BYTE(put_buffer ) \ + } else { \ + buffer[0] = (JOCTET)(put_buffer >> 24); \ + buffer[1] = (JOCTET)(put_buffer >> 16); \ + buffer[2] = (JOCTET)(put_buffer >> 8); \ + buffer[3] = (JOCTET)(put_buffer); \ + buffer += 4; \ } \ } -#if !defined(_WIN32) && !defined(SIZEOF_SIZE_T) -#error Cannot determine word size #endif -#if SIZEOF_SIZE_T == 8 || defined(_WIN64) - -#define EMIT_BITS(code, size) { \ - CHECKBUF47() \ - PUT_BITS(code, size) \ -} - -#define EMIT_CODE(code, size) { \ - temp2 &= (((JLONG)1) << nbits) - 1; \ - CHECKBUF31() \ - PUT_BITS(code, size) \ - PUT_BITS(temp2, nbits) \ +/* Fill the bit buffer to capacity with the leading bits from code, then output + * the bit buffer and put the remaining bits from code into the bit buffer. + */ +#define PUT_AND_FLUSH(code, size) { \ + put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \ + FLUSH() \ + free_bits += BIT_BUF_SIZE; \ + put_buffer = code; \ } -#else - -#define EMIT_BITS(code, size) { \ - PUT_BITS(code, size) \ - CHECKBUF15() \ +/* Insert code into the bit buffer and output the bit buffer if needed. + * NOTE: We can't flush with free_bits == 0, since the left shift in + * PUT_AND_FLUSH() would have undefined behavior. + */ +#define PUT_BITS(code, size) { \ + free_bits -= size; \ + if (free_bits < 0) \ + PUT_AND_FLUSH(code, size) \ + else \ + put_buffer = (put_buffer << size) | code; \ } -#define EMIT_CODE(code, size) { \ - temp2 &= (((JLONG)1) << nbits) - 1; \ - PUT_BITS(code, size) \ - CHECKBUF15() \ - PUT_BITS(temp2, nbits) \ - CHECKBUF15() \ +#define PUT_CODE(code, size) { \ + temp &= (((JLONG)1) << nbits) - 1; \ + temp |= code << nbits; \ + nbits += size; \ + PUT_BITS(temp, nbits) \ } -#endif - /* Although it is exceedingly rare, it is possible for a Huffman-encoded * coefficient block to be larger than the 128-byte unencoded block. For each @@ -444,6 +472,7 @@ dump_buffer(working_state *state) #define STORE_BUFFER() { \ if (localbuf) { \ + size_t bytes, bytestocopy; \ bytes = buffer - _buffer; \ buffer = _buffer; \ while (bytes > 0) { \ @@ -466,20 +495,46 @@ dump_buffer(working_state *state) LOCAL(boolean) flush_bits(working_state *state) { - JOCTET _buffer[BUFSIZE], *buffer; - size_t put_buffer; int put_bits; - size_t bytes, bytestocopy; int localbuf = 0; + JOCTET _buffer[BUFSIZE], *buffer, temp; + simd_bit_buf_type put_buffer; int put_bits; + int localbuf = 0; + + if (state->simd) { +#if defined(__aarch64__) && !defined(NEON_INTRINSICS) + put_bits = state->cur.free_bits; +#else + put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits; +#endif + put_buffer = state->cur.put_buffer.simd; + } else { + put_bits = BIT_BUF_SIZE - state->cur.free_bits; + put_buffer = state->cur.put_buffer.c; + } - put_buffer = state->cur.put_buffer; - put_bits = state->cur.put_bits; LOAD_BUFFER() - /* fill any partial byte with ones */ - PUT_BITS(0x7F, 7) - while (put_bits >= 8) EMIT_BYTE() + while (put_bits >= 8) { + put_bits -= 8; + temp = (JOCTET)(put_buffer >> put_bits); + EMIT_BYTE(temp) + } + if (put_bits) { + /* fill partial byte with ones */ + temp = (JOCTET)((put_buffer << (8 - put_bits)) | (0xFF >> put_bits)); + EMIT_BYTE(temp) + } - state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ - state->cur.put_bits = 0; + if (state->simd) { /* and reset bit buffer to empty */ + state->cur.put_buffer.simd = 0; +#if defined(__aarch64__) && !defined(NEON_INTRINSICS) + state->cur.free_bits = 0; +#else + state->cur.free_bits = SIMD_BIT_BUF_SIZE; +#endif + } else { + state->cur.put_buffer.c = 0; + state->cur.free_bits = BIT_BUF_SIZE; + } STORE_BUFFER() return TRUE; @@ -493,7 +548,7 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val, c_derived_tbl *dctbl, c_derived_tbl *actbl) { JOCTET _buffer[BUFSIZE], *buffer; - size_t bytes, bytestocopy; int localbuf = 0; + int localbuf = 0; LOAD_BUFFER() @@ -509,53 +564,41 @@ LOCAL(boolean) encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_derived_tbl *dctbl, c_derived_tbl *actbl) { - int temp, temp2, temp3; - int nbits; - int r, code, size; + int temp, nbits, free_bits; + bit_buf_type put_buffer; JOCTET _buffer[BUFSIZE], *buffer; - size_t put_buffer; int put_bits; - int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0]; - size_t bytes, bytestocopy; int localbuf = 0; + int localbuf = 0; - put_buffer = state->cur.put_buffer; - put_bits = state->cur.put_bits; + free_bits = state->cur.free_bits; + put_buffer = state->cur.put_buffer.c; LOAD_BUFFER() /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = temp2 = block[0] - last_dc_val; + temp = block[0] - last_dc_val; /* This is a well-known technique for obtaining the absolute value without a * branch. It is derived from an assembly language technique presented in * "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by - * Agner Fog. + * Agner Fog. This code assumes we are on a two's complement machine. */ - temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); - temp ^= temp3; - temp -= temp3; - - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2 += temp3; + nbits = temp >> (CHAR_BIT * sizeof(int) - 1); + temp += nbits; + nbits ^= temp; /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = JPEG_NBITS(temp); - - /* Emit the Huffman-coded symbol for the number of bits */ - code = dctbl->ehufco[nbits]; - size = dctbl->ehufsi[nbits]; - EMIT_BITS(code, size) + nbits = JPEG_NBITS(nbits); - /* Mask off any extra bits in code */ - temp2 &= (((JLONG)1) << nbits) - 1; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - EMIT_BITS(temp2, nbits) + /* Emit the Huffman-coded symbol for the number of bits. + * Emit that number of bits of the value, if positive, + * or the complement of its magnitude, if negative. + */ + PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]) /* Encode the AC coefficients per section F.1.2.2 */ - r = 0; /* r = run length of zeros */ + { + int r = 0; /* r = run length of zeros */ /* Manually unroll the k loop to eliminate the counter variable. This * improves performance greatly on systems with a limited number of @@ -563,51 +606,46 @@ encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, */ #define kloop(jpeg_natural_order_of_k) { \ if ((temp = block[jpeg_natural_order_of_k]) == 0) { \ - r++; \ + r += 16; \ } else { \ - temp2 = temp; \ /* Branch-less absolute value, bitwise complement, etc., same as above */ \ - temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \ - temp ^= temp3; \ - temp -= temp3; \ - temp2 += temp3; \ - nbits = JPEG_NBITS_NONZERO(temp); \ + nbits = temp >> (CHAR_BIT * sizeof(int) - 1); \ + temp += nbits; \ + nbits ^= temp; \ + nbits = JPEG_NBITS_NONZERO(nbits); \ /* if run length > 15, must emit special run-length-16 codes (0xF0) */ \ - while (r > 15) { \ - EMIT_BITS(code_0xf0, size_0xf0) \ - r -= 16; \ + while (r >= 16 * 16) { \ + r -= 16 * 16; \ + PUT_BITS(actbl->ehufco[0xf0], actbl->ehufsi[0xf0]) \ } \ /* Emit Huffman symbol for run length / number of bits */ \ - temp3 = (r << 4) + nbits; \ - code = actbl->ehufco[temp3]; \ - size = actbl->ehufsi[temp3]; \ - EMIT_CODE(code, size) \ + r += nbits; \ + PUT_CODE(actbl->ehufco[r], actbl->ehufsi[r]) \ r = 0; \ } \ } - /* One iteration for each value in jpeg_natural_order[] */ - kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3); - kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18); - kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26); - kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27); - kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21); - kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57); - kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15); - kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58); - kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39); - kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47); - kloop(55); kloop(62); kloop(63); - - /* If the last coef(s) were zero, emit an end-of-block code */ - if (r > 0) { - code = actbl->ehufco[0]; - size = actbl->ehufsi[0]; - EMIT_BITS(code, size) + /* One iteration for each value in jpeg_natural_order[] */ + kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3); + kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18); + kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26); + kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27); + kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21); + kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57); + kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15); + kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58); + kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39); + kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47); + kloop(55); kloop(62); kloop(63); + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) { + PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0]) + } } - state->cur.put_buffer = put_buffer; - state->cur.put_bits = put_bits; + state->cur.put_buffer.c = put_buffer; + state->cur.free_bits = free_bits; STORE_BUFFER() return TRUE; @@ -654,8 +692,9 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Load up working state */ state.next_output_byte = cinfo->dest->next_output_byte; state.free_in_buffer = cinfo->dest->free_in_buffer; - ASSIGN_STATE(state.cur, entropy->saved); + state.cur = entropy->saved; state.cinfo = cinfo; + state.simd = entropy->simd; /* Emit restart marker if needed */ if (cinfo->restart_interval) { @@ -694,7 +733,7 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Completed MCU, so update state */ cinfo->dest->next_output_byte = state.next_output_byte; cinfo->dest->free_in_buffer = state.free_in_buffer; - ASSIGN_STATE(entropy->saved, state.cur); + entropy->saved = state.cur; /* Update restart-interval state too */ if (cinfo->restart_interval) { @@ -723,8 +762,9 @@ finish_pass_huff(j_compress_ptr cinfo) /* Load up working state ... flush_bits needs it */ state.next_output_byte = cinfo->dest->next_output_byte; state.free_in_buffer = cinfo->dest->free_in_buffer; - ASSIGN_STATE(state.cur, entropy->saved); + state.cur = entropy->saved; state.cinfo = cinfo; + state.simd = entropy->simd; /* Flush out the last data */ if (!flush_bits(&state)) @@ -733,7 +773,7 @@ finish_pass_huff(j_compress_ptr cinfo) /* Update state */ cinfo->dest->next_output_byte = state.next_output_byte; cinfo->dest->free_in_buffer = state.free_in_buffer; - ASSIGN_STATE(entropy->saved, state.cur); + entropy->saved = state.cur; } diff --git a/3rdparty/libjpeg-turbo/src/jcphuff.c b/3rdparty/libjpeg-turbo/src/jcphuff.c index a8b94bed84b8..bd14fc27d5e2 100644 --- a/3rdparty/libjpeg-turbo/src/jcphuff.c +++ b/3rdparty/libjpeg-turbo/src/jcphuff.c @@ -4,8 +4,9 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1995-1997, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2011, 2015, 2018, D. R. Commander. + * Copyright (C) 2011, 2015, 2018, 2021, D. R. Commander. * Copyright (C) 2016, 2018, Matthieu Darbois. + * Copyright (C) 2020, Arm Limited. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -51,15 +52,19 @@ * flags (this defines __thumb__). */ -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__)) +#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || \ + defined(_M_ARM64) #if !defined(__thumb__) || defined(__thumb2__) #define USE_CLZ_INTRINSIC #endif #endif #ifdef USE_CLZ_INTRINSIC +#if defined(_MSC_VER) && !defined(__clang__) +#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) +#else #define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) +#endif #define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) #else #include "jpeg_nbits_table.h" @@ -169,24 +174,26 @@ INLINE METHODDEF(int) count_zeroes(size_t *x) { - int result; #if defined(HAVE_BUILTIN_CTZL) + int result; result = __builtin_ctzl(*x); *x >>= result; #elif defined(HAVE_BITSCANFORWARD64) + unsigned long result; _BitScanForward64(&result, *x); *x >>= result; #elif defined(HAVE_BITSCANFORWARD) + unsigned long result; _BitScanForward(&result, *x); *x >>= result; #else - result = 0; + int result = 0; while ((*x & 1) == 0) { ++result; *x >>= 1; } #endif - return result; + return (int)result; } @@ -860,7 +867,7 @@ encode_mcu_AC_refine_prepare(const JCOEF *block, #define ENCODE_COEFS_AC_REFINE(label) { \ while (zerobits) { \ - int idx = count_zeroes(&zerobits); \ + idx = count_zeroes(&zerobits); \ r += idx; \ cabsvalue += idx; \ signbits >>= idx; \ @@ -917,7 +924,7 @@ METHODDEF(boolean) encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; - register int temp, r; + register int temp, r, idx; char *BR_buffer; unsigned int BR; int Sl = cinfo->Se - cinfo->Ss + 1; @@ -968,7 +975,7 @@ encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data) if (zerobits) { int diff = ((absvalues + DCTSIZE2 / 2) - cabsvalue); - int idx = count_zeroes(&zerobits); + idx = count_zeroes(&zerobits); signbits >>= idx; idx += diff; r += idx; diff --git a/3rdparty/libjpeg-turbo/src/jcsample.c b/3rdparty/libjpeg-turbo/src/jcsample.c index bd27b84e068a..e8515ebf0fce 100644 --- a/3rdparty/libjpeg-turbo/src/jcsample.c +++ b/3rdparty/libjpeg-turbo/src/jcsample.c @@ -6,7 +6,7 @@ * libjpeg-turbo Modifications: * Copyright 2009 Pierre Ossman for Cendio AB * Copyright (C) 2014, MIPS Technologies, Inc., California. - * Copyright (C) 2015, D. R. Commander. + * Copyright (C) 2015, 2019, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -103,7 +103,7 @@ expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols, if (numcols > 0) { for (row = 0; row < num_rows; row++) { ptr = image_data[row] + input_cols; - pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ + pixval = ptr[-1]; for (count = numcols; count > 0; count--) *ptr++ = pixval; } @@ -174,7 +174,7 @@ int_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, for (v = 0; v < v_expand; v++) { inptr = input_data[inrow + v] + outcol_h; for (h = 0; h < h_expand; h++) { - outvalue += (JLONG)GETJSAMPLE(*inptr++); + outvalue += (JLONG)(*inptr++); } } *outptr++ = (JSAMPLE)((outvalue + numpix2) / numpix); @@ -237,8 +237,7 @@ h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, inptr = input_data[outrow]; bias = 0; /* bias = 0,1,0,1,... for successive samples */ for (outcol = 0; outcol < output_cols; outcol++) { - *outptr++ = - (JSAMPLE)((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + bias) >> 1); + *outptr++ = (JSAMPLE)((inptr[0] + inptr[1] + bias) >> 1); bias ^= 1; /* 0=>1, 1=>0 */ inptr += 2; } @@ -277,8 +276,7 @@ h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, bias = 1; /* bias = 1,2,1,2,... for successive samples */ for (outcol = 0; outcol < output_cols; outcol++) { *outptr++ = - (JSAMPLE)((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + bias) >> 2); + (JSAMPLE)((inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1] + bias) >> 2); bias ^= 3; /* 1=>2, 2=>1 */ inptr0 += 2; inptr1 += 2; } @@ -337,33 +335,25 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, below_ptr = input_data[inrow + 2]; /* Special case for first column: pretend column -1 is same as column 0 */ - membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); - neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + - GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); + membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1]; + neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] + + inptr0[0] + inptr0[2] + inptr1[0] + inptr1[2]; neighsum += neighsum; - neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); + neighsum += above_ptr[0] + above_ptr[2] + below_ptr[0] + below_ptr[2]; membersum = membersum * memberscale + neighsum * neighscale; *outptr++ = (JSAMPLE)((membersum + 32768) >> 16); inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; for (colctr = output_cols - 2; colctr > 0; colctr--) { /* sum of pixels directly mapped to this output element */ - membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); + membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1]; /* sum of edge-neighbor pixels */ - neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + - GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + - GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); + neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] + + inptr0[-1] + inptr0[2] + inptr1[-1] + inptr1[2]; /* The edge-neighbors count twice as much as corner-neighbors */ neighsum += neighsum; /* Add in the corner-neighbors */ - neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + - GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); + neighsum += above_ptr[-1] + above_ptr[2] + below_ptr[-1] + below_ptr[2]; /* form final output scaled up by 2^16 */ membersum = membersum * memberscale + neighsum * neighscale; /* round, descale and output it */ @@ -372,15 +362,11 @@ h2v2_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, } /* Special case for last column */ - membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); - neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + - GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); + membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1]; + neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] + + inptr0[-1] + inptr0[1] + inptr1[-1] + inptr1[1]; neighsum += neighsum; - neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); + neighsum += above_ptr[-1] + above_ptr[1] + below_ptr[-1] + below_ptr[1]; membersum = membersum * memberscale + neighsum * neighscale; *outptr = (JSAMPLE)((membersum + 32768) >> 16); @@ -429,21 +415,18 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, below_ptr = input_data[outrow + 1]; /* Special case for first column */ - colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + - GETJSAMPLE(*inptr); - membersum = GETJSAMPLE(*inptr++); - nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + - GETJSAMPLE(*inptr); + colsum = (*above_ptr++) + (*below_ptr++) + inptr[0]; + membersum = *inptr++; + nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0]; neighsum = colsum + (colsum - membersum) + nextcolsum; membersum = membersum * memberscale + neighsum * neighscale; *outptr++ = (JSAMPLE)((membersum + 32768) >> 16); lastcolsum = colsum; colsum = nextcolsum; for (colctr = output_cols - 2; colctr > 0; colctr--) { - membersum = GETJSAMPLE(*inptr++); + membersum = *inptr++; above_ptr++; below_ptr++; - nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + - GETJSAMPLE(*inptr); + nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0]; neighsum = lastcolsum + (colsum - membersum) + nextcolsum; membersum = membersum * memberscale + neighsum * neighscale; *outptr++ = (JSAMPLE)((membersum + 32768) >> 16); @@ -451,7 +434,7 @@ fullsize_smooth_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, } /* Special case for last column */ - membersum = GETJSAMPLE(*inptr); + membersum = *inptr; neighsum = lastcolsum + (colsum - membersum) + colsum; membersum = membersum * memberscale + neighsum * neighscale; *outptr = (JSAMPLE)((membersum + 32768) >> 16); diff --git a/3rdparty/libjpeg-turbo/src/jdapistd.c b/3rdparty/libjpeg-turbo/src/jdapistd.c index 38bd1110d9b3..695a6200992d 100644 --- a/3rdparty/libjpeg-turbo/src/jdapistd.c +++ b/3rdparty/libjpeg-turbo/src/jdapistd.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1994-1996, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2015-2018, 2020, D. R. Commander. + * Copyright (C) 2010, 2015-2020, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. @@ -319,6 +319,8 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) { JDIMENSION n; my_master_ptr master = (my_master_ptr)cinfo->master; + JSAMPLE dummy_sample[1] = { 0 }; + JSAMPROW dummy_row = dummy_sample; JSAMPARRAY scanlines = NULL; void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, @@ -329,6 +331,10 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) if (cinfo->cconvert && cinfo->cconvert->color_convert) { color_convert = cinfo->cconvert->color_convert; cinfo->cconvert->color_convert = noop_convert; + /* This just prevents UBSan from complaining about adding 0 to a NULL + * pointer. The pointer isn't actually used. + */ + scanlines = &dummy_row; } if (cinfo->cquantize && cinfo->cquantize->color_quantize) { @@ -532,6 +538,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) * decoded coefficients. This is ~5% faster for large subsets, but * it's tough to tell a difference for smaller images. */ + if (!cinfo->entropy->insufficient_data) + cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row; (*cinfo->entropy->decode_mcu) (cinfo, NULL); } } diff --git a/3rdparty/libjpeg-turbo/src/jdarith.c b/3rdparty/libjpeg-turbo/src/jdarith.c index 6002481e242c..7f0d3a785c39 100644 --- a/3rdparty/libjpeg-turbo/src/jdarith.c +++ b/3rdparty/libjpeg-turbo/src/jdarith.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Developed 1997-2015 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2015-2018, D. R. Commander. + * Copyright (C) 2015-2020, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -80,7 +80,7 @@ get_byte(j_decompress_ptr cinfo) if (!(*src->fill_input_buffer) (cinfo)) ERREXIT(cinfo, JERR_CANT_SUSPEND); src->bytes_in_buffer--; - return GETJOCTET(*src->next_input_byte++); + return *src->next_input_byte++; } @@ -665,8 +665,16 @@ start_pass(j_decompress_ptr cinfo) for (ci = 0; ci < cinfo->comps_in_scan; ci++) { int coefi, cindex = cinfo->cur_comp_info[ci]->component_index; int *coef_bit_ptr = &cinfo->coef_bits[cindex][0]; + int *prev_coef_bit_ptr = + &cinfo->coef_bits[cindex + cinfo->num_components][0]; if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); + for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) { + if (cinfo->input_scan_number > 1) + prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi]; + else + prev_coef_bit_ptr[coefi] = 0; + } for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; if (cinfo->Ah != expected) @@ -727,6 +735,7 @@ start_pass(j_decompress_ptr cinfo) entropy->c = 0; entropy->a = 0; entropy->ct = -16; /* force reading 2 initial bytes to fill C */ + entropy->pub.insufficient_data = FALSE; /* Initialize restart counter */ entropy->restarts_to_go = cinfo->restart_interval; @@ -763,7 +772,7 @@ jinit_arith_decoder(j_decompress_ptr cinfo) int *coef_bit_ptr, ci; cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, - cinfo->num_components * DCTSIZE2 * + cinfo->num_components * 2 * DCTSIZE2 * sizeof(int)); coef_bit_ptr = &cinfo->coef_bits[0][0]; for (ci = 0; ci < cinfo->num_components; ci++) diff --git a/3rdparty/libjpeg-turbo/src/jdcoefct.c b/3rdparty/libjpeg-turbo/src/jdcoefct.c index 2ba6aa11e4d2..15e6cded628e 100644 --- a/3rdparty/libjpeg-turbo/src/jdcoefct.c +++ b/3rdparty/libjpeg-turbo/src/jdcoefct.c @@ -5,7 +5,7 @@ * Copyright (C) 1994-1997, Thomas G. Lane. * libjpeg-turbo Modifications: * Copyright 2009 Pierre Ossman for Cendio AB - * Copyright (C) 2010, 2015-2016, D. R. Commander. + * Copyright (C) 2010, 2015-2016, 2019-2020, D. R. Commander. * Copyright (C) 2015, 2020, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. @@ -102,6 +102,8 @@ decompress_onepass(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ jzero_far((void *)coef->MCU_buffer[0], (size_t)(cinfo->blocks_in_MCU * sizeof(JBLOCK))); + if (!cinfo->entropy->insufficient_data) + cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row; if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; @@ -227,6 +229,8 @@ consume_data(j_decompress_ptr cinfo) } } } + if (!cinfo->entropy->insufficient_data) + cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row; /* Try to fetch the MCU. */ if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ @@ -326,19 +330,22 @@ decompress_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) #ifdef BLOCK_SMOOTHING_SUPPORTED /* - * This code applies interblock smoothing as described by section K.8 - * of the JPEG standard: the first 5 AC coefficients are estimated from - * the DC values of a DCT block and its 8 neighboring blocks. + * This code applies interblock smoothing; the first 9 AC coefficients are + * estimated from the DC values of a DCT block and its 24 neighboring blocks. * We apply smoothing only for progressive JPEG decoding, and only if * the coefficients it can estimate are not yet known to full precision. */ -/* Natural-order array positions of the first 5 zigzag-order coefficients */ +/* Natural-order array positions of the first 9 zigzag-order coefficients */ #define Q01_POS 1 #define Q10_POS 8 #define Q20_POS 16 #define Q11_POS 9 #define Q02_POS 2 +#define Q03_POS 3 +#define Q12_POS 10 +#define Q21_POS 17 +#define Q30_POS 24 /* * Determine whether block smoothing is applicable and safe. @@ -356,8 +363,8 @@ smoothing_ok(j_decompress_ptr cinfo) int ci, coefi; jpeg_component_info *compptr; JQUANT_TBL *qtable; - int *coef_bits; - int *coef_bits_latch; + int *coef_bits, *prev_coef_bits; + int *coef_bits_latch, *prev_coef_bits_latch; if (!cinfo->progressive_mode || cinfo->coef_bits == NULL) return FALSE; @@ -366,34 +373,47 @@ smoothing_ok(j_decompress_ptr cinfo) if (coef->coef_bits_latch == NULL) coef->coef_bits_latch = (int *) (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, - cinfo->num_components * + cinfo->num_components * 2 * (SAVED_COEFS * sizeof(int))); coef_bits_latch = coef->coef_bits_latch; + prev_coef_bits_latch = + &coef->coef_bits_latch[cinfo->num_components * SAVED_COEFS]; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { /* All components' quantization values must already be latched. */ if ((qtable = compptr->quant_table) == NULL) return FALSE; - /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ + /* Verify DC & first 9 AC quantizers are nonzero to avoid zero-divide. */ if (qtable->quantval[0] == 0 || qtable->quantval[Q01_POS] == 0 || qtable->quantval[Q10_POS] == 0 || qtable->quantval[Q20_POS] == 0 || qtable->quantval[Q11_POS] == 0 || - qtable->quantval[Q02_POS] == 0) + qtable->quantval[Q02_POS] == 0 || + qtable->quantval[Q03_POS] == 0 || + qtable->quantval[Q12_POS] == 0 || + qtable->quantval[Q21_POS] == 0 || + qtable->quantval[Q30_POS] == 0) return FALSE; /* DC values must be at least partly known for all components. */ coef_bits = cinfo->coef_bits[ci]; + prev_coef_bits = cinfo->coef_bits[ci + cinfo->num_components]; if (coef_bits[0] < 0) return FALSE; + coef_bits_latch[0] = coef_bits[0]; /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ - for (coefi = 1; coefi <= 5; coefi++) { + for (coefi = 1; coefi < SAVED_COEFS; coefi++) { + if (cinfo->input_scan_number > 1) + prev_coef_bits_latch[coefi] = prev_coef_bits[coefi]; + else + prev_coef_bits_latch[coefi] = -1; coef_bits_latch[coefi] = coef_bits[coefi]; if (coef_bits[coefi] != 0) smoothing_useful = TRUE; } coef_bits_latch += SAVED_COEFS; + prev_coef_bits_latch += SAVED_COEFS; } return smoothing_useful; @@ -412,17 +432,20 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) JDIMENSION block_num, last_block_column; int ci, block_row, block_rows, access_rows; JBLOCKARRAY buffer; - JBLOCKROW buffer_ptr, prev_block_row, next_block_row; + JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row; + JBLOCKROW next_block_row, next_next_block_row; JSAMPARRAY output_ptr; JDIMENSION output_col; jpeg_component_info *compptr; inverse_DCT_method_ptr inverse_DCT; - boolean first_row, last_row; + boolean change_dc; JCOEF *workspace; int *coef_bits; JQUANT_TBL *quanttbl; - JLONG Q00, Q01, Q02, Q10, Q11, Q20, num; - int DC1, DC2, DC3, DC4, DC5, DC6, DC7, DC8, DC9; + JLONG Q00, Q01, Q02, Q03 = 0, Q10, Q11, Q12 = 0, Q20, Q21 = 0, Q30 = 0, num; + int DC01, DC02, DC03, DC04, DC05, DC06, DC07, DC08, DC09, DC10, DC11, DC12, + DC13, DC14, DC15, DC16, DC17, DC18, DC19, DC20, DC21, DC22, DC23, DC24, + DC25; int Al, pred; /* Keep a local variable to avoid looking it up more than once */ @@ -434,10 +457,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) if (cinfo->input_scan_number == cinfo->output_scan_number) { /* If input is working on current scan, we ordinarily want it to * have completed the current row. But if input scan is DC, - * we want it to keep one row ahead so that next block row's DC + * we want it to keep two rows ahead so that next two block rows' DC * values are up to date. */ - JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; + JDIMENSION delta = (cinfo->Ss == 0) ? 2 : 0; if (cinfo->input_iMCU_row > cinfo->output_iMCU_row + delta) break; } @@ -452,34 +475,53 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) if (!compptr->component_needed) continue; /* Count non-dummy DCT block rows in this iMCU row. */ - if (cinfo->output_iMCU_row < last_iMCU_row) { + if (cinfo->output_iMCU_row < last_iMCU_row - 1) { + block_rows = compptr->v_samp_factor; + access_rows = block_rows * 3; /* this and next two iMCU rows */ + } else if (cinfo->output_iMCU_row < last_iMCU_row) { block_rows = compptr->v_samp_factor; access_rows = block_rows * 2; /* this and next iMCU row */ - last_row = FALSE; } else { /* NB: can't use last_row_height here; it is input-side-dependent! */ block_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor); if (block_rows == 0) block_rows = compptr->v_samp_factor; access_rows = block_rows; /* this iMCU row only */ - last_row = TRUE; } /* Align the virtual buffer for this component. */ - if (cinfo->output_iMCU_row > 0) { - access_rows += compptr->v_samp_factor; /* prior iMCU row too */ + if (cinfo->output_iMCU_row > 1) { + access_rows += 2 * compptr->v_samp_factor; /* prior two iMCU rows too */ + buffer = (*cinfo->mem->access_virt_barray) + ((j_common_ptr)cinfo, coef->whole_image[ci], + (cinfo->output_iMCU_row - 2) * compptr->v_samp_factor, + (JDIMENSION)access_rows, FALSE); + buffer += 2 * compptr->v_samp_factor; /* point to current iMCU row */ + } else if (cinfo->output_iMCU_row > 0) { buffer = (*cinfo->mem->access_virt_barray) ((j_common_ptr)cinfo, coef->whole_image[ci], (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, (JDIMENSION)access_rows, FALSE); buffer += compptr->v_samp_factor; /* point to current iMCU row */ - first_row = FALSE; } else { buffer = (*cinfo->mem->access_virt_barray) ((j_common_ptr)cinfo, coef->whole_image[ci], (JDIMENSION)0, (JDIMENSION)access_rows, FALSE); - first_row = TRUE; } - /* Fetch component-dependent info */ - coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); + /* Fetch component-dependent info. + * If the current scan is incomplete, then we use the component-dependent + * info from the previous scan. + */ + if (cinfo->output_iMCU_row > cinfo->master->last_good_iMCU_row) + coef_bits = + coef->coef_bits_latch + ((ci + cinfo->num_components) * SAVED_COEFS); + else + coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); + + /* We only do DC interpolation if no AC coefficient data is available. */ + change_dc = + coef_bits[1] == -1 && coef_bits[2] == -1 && coef_bits[3] == -1 && + coef_bits[4] == -1 && coef_bits[5] == -1 && coef_bits[6] == -1 && + coef_bits[7] == -1 && coef_bits[8] == -1 && coef_bits[9] == -1; + quanttbl = compptr->quant_table; Q00 = quanttbl->quantval[0]; Q01 = quanttbl->quantval[Q01_POS]; @@ -487,27 +529,51 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) Q20 = quanttbl->quantval[Q20_POS]; Q11 = quanttbl->quantval[Q11_POS]; Q02 = quanttbl->quantval[Q02_POS]; + if (change_dc) { + Q03 = quanttbl->quantval[Q03_POS]; + Q12 = quanttbl->quantval[Q12_POS]; + Q21 = quanttbl->quantval[Q21_POS]; + Q30 = quanttbl->quantval[Q30_POS]; + } inverse_DCT = cinfo->idct->inverse_DCT[ci]; output_ptr = output_buf[ci]; /* Loop over all DCT blocks to be processed. */ for (block_row = 0; block_row < block_rows; block_row++) { buffer_ptr = buffer[block_row] + cinfo->master->first_MCU_col[ci]; - if (first_row && block_row == 0) + + if (block_row > 0 || cinfo->output_iMCU_row > 0) + prev_block_row = + buffer[block_row - 1] + cinfo->master->first_MCU_col[ci]; + else prev_block_row = buffer_ptr; + + if (block_row > 1 || cinfo->output_iMCU_row > 1) + prev_prev_block_row = + buffer[block_row - 2] + cinfo->master->first_MCU_col[ci]; + else + prev_prev_block_row = prev_block_row; + + if (block_row < block_rows - 1 || cinfo->output_iMCU_row < last_iMCU_row) + next_block_row = + buffer[block_row + 1] + cinfo->master->first_MCU_col[ci]; else - prev_block_row = buffer[block_row - 1] + - cinfo->master->first_MCU_col[ci]; - if (last_row && block_row == block_rows - 1) next_block_row = buffer_ptr; + + if (block_row < block_rows - 2 || + cinfo->output_iMCU_row < last_iMCU_row - 1) + next_next_block_row = + buffer[block_row + 2] + cinfo->master->first_MCU_col[ci]; else - next_block_row = buffer[block_row + 1] + - cinfo->master->first_MCU_col[ci]; + next_next_block_row = next_block_row; + /* We fetch the surrounding DC values using a sliding-register approach. - * Initialize all nine here so as to do the right thing on narrow pics. + * Initialize all 25 here so as to do the right thing on narrow pics. */ - DC1 = DC2 = DC3 = (int)prev_block_row[0][0]; - DC4 = DC5 = DC6 = (int)buffer_ptr[0][0]; - DC7 = DC8 = DC9 = (int)next_block_row[0][0]; + DC01 = DC02 = DC03 = DC04 = DC05 = (int)prev_prev_block_row[0][0]; + DC06 = DC07 = DC08 = DC09 = DC10 = (int)prev_block_row[0][0]; + DC11 = DC12 = DC13 = DC14 = DC15 = (int)buffer_ptr[0][0]; + DC16 = DC17 = DC18 = DC19 = DC20 = (int)next_block_row[0][0]; + DC21 = DC22 = DC23 = DC24 = DC25 = (int)next_next_block_row[0][0]; output_col = 0; last_block_column = compptr->width_in_blocks - 1; for (block_num = cinfo->master->first_MCU_col[ci]; @@ -515,18 +581,39 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) /* Fetch current DCT block into workspace so we can modify it. */ jcopy_block_row(buffer_ptr, (JBLOCKROW)workspace, (JDIMENSION)1); /* Update DC values */ - if (block_num < last_block_column) { - DC3 = (int)prev_block_row[1][0]; - DC6 = (int)buffer_ptr[1][0]; - DC9 = (int)next_block_row[1][0]; + if (block_num == cinfo->master->first_MCU_col[ci] && + block_num < last_block_column) { + DC04 = (int)prev_prev_block_row[1][0]; + DC09 = (int)prev_block_row[1][0]; + DC14 = (int)buffer_ptr[1][0]; + DC19 = (int)next_block_row[1][0]; + DC24 = (int)next_next_block_row[1][0]; } - /* Compute coefficient estimates per K.8. - * An estimate is applied only if coefficient is still zero, - * and is not known to be fully accurate. + if (block_num + 1 < last_block_column) { + DC05 = (int)prev_prev_block_row[2][0]; + DC10 = (int)prev_block_row[2][0]; + DC15 = (int)buffer_ptr[2][0]; + DC20 = (int)next_block_row[2][0]; + DC25 = (int)next_next_block_row[2][0]; + } + /* If DC interpolation is enabled, compute coefficient estimates using + * a Gaussian-like kernel, keeping the averages of the DC values. + * + * If DC interpolation is disabled, compute coefficient estimates using + * an algorithm similar to the one described in Section K.8 of the JPEG + * standard, except applied to a 5x5 window rather than a 3x3 window. + * + * An estimate is applied only if the coefficient is still zero and is + * not known to be fully accurate. */ /* AC01 */ if ((Al = coef_bits[1]) != 0 && workspace[1] == 0) { - num = 36 * Q00 * (DC4 - DC6); + num = Q00 * (change_dc ? + (-DC01 - DC02 + DC04 + DC05 - 3 * DC06 + 13 * DC07 - + 13 * DC09 + 3 * DC10 - 3 * DC11 + 38 * DC12 - 38 * DC14 + + 3 * DC15 - 3 * DC16 + 13 * DC17 - 13 * DC19 + 3 * DC20 - + DC21 - DC22 + DC24 + DC25) : + (-7 * DC11 + 50 * DC12 - 50 * DC14 + 7 * DC15)); if (num >= 0) { pred = (int)(((Q01 << 7) + num) / (Q01 << 8)); if (Al > 0 && pred >= (1 << Al)) @@ -541,7 +628,12 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } /* AC10 */ if ((Al = coef_bits[2]) != 0 && workspace[8] == 0) { - num = 36 * Q00 * (DC2 - DC8); + num = Q00 * (change_dc ? + (-DC01 - 3 * DC02 - 3 * DC03 - 3 * DC04 - DC05 - DC06 + + 13 * DC07 + 38 * DC08 + 13 * DC09 - DC10 + DC16 - + 13 * DC17 - 38 * DC18 - 13 * DC19 + DC20 + DC21 + + 3 * DC22 + 3 * DC23 + 3 * DC24 + DC25) : + (-7 * DC03 + 50 * DC08 - 50 * DC18 + 7 * DC23)); if (num >= 0) { pred = (int)(((Q10 << 7) + num) / (Q10 << 8)); if (Al > 0 && pred >= (1 << Al)) @@ -556,7 +648,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } /* AC20 */ if ((Al = coef_bits[3]) != 0 && workspace[16] == 0) { - num = 9 * Q00 * (DC2 + DC8 - 2 * DC5); + num = Q00 * (change_dc ? + (DC03 + 2 * DC07 + 7 * DC08 + 2 * DC09 - 5 * DC12 - 14 * DC13 - + 5 * DC14 + 2 * DC17 + 7 * DC18 + 2 * DC19 + DC23) : + (-DC03 + 13 * DC08 - 24 * DC13 + 13 * DC18 - DC23)); if (num >= 0) { pred = (int)(((Q20 << 7) + num) / (Q20 << 8)); if (Al > 0 && pred >= (1 << Al)) @@ -571,7 +666,11 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } /* AC11 */ if ((Al = coef_bits[4]) != 0 && workspace[9] == 0) { - num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9); + num = Q00 * (change_dc ? + (-DC01 + DC05 + 9 * DC07 - 9 * DC09 - 9 * DC17 + + 9 * DC19 + DC21 - DC25) : + (DC10 + DC16 - 10 * DC17 + 10 * DC19 - DC02 - DC20 + DC22 - + DC24 + DC04 - DC06 + 10 * DC07 - 10 * DC09)); if (num >= 0) { pred = (int)(((Q11 << 7) + num) / (Q11 << 8)); if (Al > 0 && pred >= (1 << Al)) @@ -586,7 +685,10 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } /* AC02 */ if ((Al = coef_bits[5]) != 0 && workspace[2] == 0) { - num = 9 * Q00 * (DC4 + DC6 - 2 * DC5); + num = Q00 * (change_dc ? + (2 * DC07 - 5 * DC08 + 2 * DC09 + DC11 + 7 * DC12 - 14 * DC13 + + 7 * DC14 + DC15 + 2 * DC17 - 5 * DC18 + 2 * DC19) : + (-DC11 + 13 * DC12 - 24 * DC13 + 13 * DC14 - DC15)); if (num >= 0) { pred = (int)(((Q02 << 7) + num) / (Q02 << 8)); if (Al > 0 && pred >= (1 << Al)) @@ -599,14 +701,96 @@ decompress_smooth_data(j_decompress_ptr cinfo, JSAMPIMAGE output_buf) } workspace[2] = (JCOEF)pred; } + if (change_dc) { + /* AC03 */ + if ((Al = coef_bits[6]) != 0 && workspace[3] == 0) { + num = Q00 * (DC07 - DC09 + 2 * DC12 - 2 * DC14 + DC17 - DC19); + if (num >= 0) { + pred = (int)(((Q03 << 7) + num) / (Q03 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + } else { + pred = (int)(((Q03 << 7) - num) / (Q03 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + pred = -pred; + } + workspace[3] = (JCOEF)pred; + } + /* AC12 */ + if ((Al = coef_bits[7]) != 0 && workspace[10] == 0) { + num = Q00 * (DC07 - 3 * DC08 + DC09 - DC17 + 3 * DC18 - DC19); + if (num >= 0) { + pred = (int)(((Q12 << 7) + num) / (Q12 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + } else { + pred = (int)(((Q12 << 7) - num) / (Q12 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + pred = -pred; + } + workspace[10] = (JCOEF)pred; + } + /* AC21 */ + if ((Al = coef_bits[8]) != 0 && workspace[17] == 0) { + num = Q00 * (DC07 - DC09 - 3 * DC12 + 3 * DC14 + DC17 - DC19); + if (num >= 0) { + pred = (int)(((Q21 << 7) + num) / (Q21 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + } else { + pred = (int)(((Q21 << 7) - num) / (Q21 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + pred = -pred; + } + workspace[17] = (JCOEF)pred; + } + /* AC30 */ + if ((Al = coef_bits[9]) != 0 && workspace[24] == 0) { + num = Q00 * (DC07 + 2 * DC08 + DC09 - DC17 - 2 * DC18 - DC19); + if (num >= 0) { + pred = (int)(((Q30 << 7) + num) / (Q30 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + } else { + pred = (int)(((Q30 << 7) - num) / (Q30 << 8)); + if (Al > 0 && pred >= (1 << Al)) + pred = (1 << Al) - 1; + pred = -pred; + } + workspace[24] = (JCOEF)pred; + } + /* coef_bits[0] is non-negative. Otherwise this function would not + * be called. + */ + num = Q00 * + (-2 * DC01 - 6 * DC02 - 8 * DC03 - 6 * DC04 - 2 * DC05 - + 6 * DC06 + 6 * DC07 + 42 * DC08 + 6 * DC09 - 6 * DC10 - + 8 * DC11 + 42 * DC12 + 152 * DC13 + 42 * DC14 - 8 * DC15 - + 6 * DC16 + 6 * DC17 + 42 * DC18 + 6 * DC19 - 6 * DC20 - + 2 * DC21 - 6 * DC22 - 8 * DC23 - 6 * DC24 - 2 * DC25); + if (num >= 0) { + pred = (int)(((Q00 << 7) + num) / (Q00 << 8)); + } else { + pred = (int)(((Q00 << 7) - num) / (Q00 << 8)); + pred = -pred; + } + workspace[0] = (JCOEF)pred; + } /* change_dc */ + /* OK, do the IDCT */ (*inverse_DCT) (cinfo, compptr, (JCOEFPTR)workspace, output_ptr, output_col); /* Advance for next column */ - DC1 = DC2; DC2 = DC3; - DC4 = DC5; DC5 = DC6; - DC7 = DC8; DC8 = DC9; - buffer_ptr++, prev_block_row++, next_block_row++; + DC01 = DC02; DC02 = DC03; DC03 = DC04; DC04 = DC05; + DC06 = DC07; DC07 = DC08; DC08 = DC09; DC09 = DC10; + DC11 = DC12; DC12 = DC13; DC13 = DC14; DC14 = DC15; + DC16 = DC17; DC17 = DC18; DC18 = DC19; DC19 = DC20; + DC21 = DC22; DC22 = DC23; DC23 = DC24; DC24 = DC25; + buffer_ptr++, prev_block_row++, next_block_row++, + prev_prev_block_row++, next_next_block_row++; output_col += compptr->_DCT_scaled_size; } output_ptr += compptr->_DCT_scaled_size; @@ -655,7 +839,7 @@ jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer) #ifdef BLOCK_SMOOTHING_SUPPORTED /* If block smoothing could be used, need a bigger window */ if (cinfo->progressive_mode) - access_rows *= 3; + access_rows *= 5; #endif coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) ((j_common_ptr)cinfo, JPOOL_IMAGE, TRUE, diff --git a/3rdparty/libjpeg-turbo/src/jdcoefct.h b/3rdparty/libjpeg-turbo/src/jdcoefct.h index c4d1943dd4db..9a0e78066364 100644 --- a/3rdparty/libjpeg-turbo/src/jdcoefct.h +++ b/3rdparty/libjpeg-turbo/src/jdcoefct.h @@ -5,6 +5,7 @@ * Copyright (C) 1994-1997, Thomas G. Lane. * libjpeg-turbo Modifications: * Copyright 2009 Pierre Ossman for Cendio AB + * Copyright (C) 2020, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. */ @@ -51,7 +52,7 @@ typedef struct { #ifdef BLOCK_SMOOTHING_SUPPORTED /* When doing block smoothing, we latch coefficient Al values here */ int *coef_bits_latch; -#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ +#define SAVED_COEFS 10 /* we save coef_bits[0..9] */ #endif } my_coef_controller; diff --git a/3rdparty/libjpeg-turbo/src/jdcol565.c b/3rdparty/libjpeg-turbo/src/jdcol565.c index 40068ef84fd2..53c7bd9187d4 100644 --- a/3rdparty/libjpeg-turbo/src/jdcol565.c +++ b/3rdparty/libjpeg-turbo/src/jdcol565.c @@ -45,9 +45,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr = *output_buf++; if (PACK_NEED_ALIGNMENT(outptr)) { - y = GETJSAMPLE(*inptr0++); - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + y = *inptr0++; + cb = *inptr1++; + cr = *inptr2++; r = range_limit[y + Crrtab[cr]]; g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; @@ -58,18 +58,18 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, num_cols--; } for (col = 0; col < (num_cols >> 1); col++) { - y = GETJSAMPLE(*inptr0++); - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + y = *inptr0++; + cb = *inptr1++; + cr = *inptr2++; r = range_limit[y + Crrtab[cr]]; g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; b = range_limit[y + Cbbtab[cb]]; rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr0++); - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + y = *inptr0++; + cb = *inptr1++; + cr = *inptr2++; r = range_limit[y + Crrtab[cr]]; g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; @@ -80,9 +80,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr += 4; } if (num_cols & 1) { - y = GETJSAMPLE(*inptr0); - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + y = *inptr0; + cb = *inptr1; + cr = *inptr2; r = range_limit[y + Crrtab[cr]]; g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))]; @@ -125,9 +125,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; if (PACK_NEED_ALIGNMENT(outptr)) { - y = GETJSAMPLE(*inptr0++); - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + y = *inptr0++; + cb = *inptr1++; + cr = *inptr2++; r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; g = range_limit[DITHER_565_G(y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], @@ -139,9 +139,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, num_cols--; } for (col = 0; col < (num_cols >> 1); col++) { - y = GETJSAMPLE(*inptr0++); - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + y = *inptr0++; + cb = *inptr1++; + cr = *inptr2++; r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; g = range_limit[DITHER_565_G(y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], @@ -150,9 +150,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, d0 = DITHER_ROTATE(d0); rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr0++); - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + y = *inptr0++; + cb = *inptr1++; + cr = *inptr2++; r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; g = range_limit[DITHER_565_G(y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], @@ -165,9 +165,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr += 4; } if (num_cols & 1) { - y = GETJSAMPLE(*inptr0); - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + y = *inptr0; + cb = *inptr1; + cr = *inptr2; r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; g = range_limit[DITHER_565_G(y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], @@ -202,32 +202,32 @@ rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; if (PACK_NEED_ALIGNMENT(outptr)) { - r = GETJSAMPLE(*inptr0++); - g = GETJSAMPLE(*inptr1++); - b = GETJSAMPLE(*inptr2++); + r = *inptr0++; + g = *inptr1++; + b = *inptr2++; rgb = PACK_SHORT_565(r, g, b); *(INT16 *)outptr = (INT16)rgb; outptr += 2; num_cols--; } for (col = 0; col < (num_cols >> 1); col++) { - r = GETJSAMPLE(*inptr0++); - g = GETJSAMPLE(*inptr1++); - b = GETJSAMPLE(*inptr2++); + r = *inptr0++; + g = *inptr1++; + b = *inptr2++; rgb = PACK_SHORT_565(r, g, b); - r = GETJSAMPLE(*inptr0++); - g = GETJSAMPLE(*inptr1++); - b = GETJSAMPLE(*inptr2++); + r = *inptr0++; + g = *inptr1++; + b = *inptr2++; rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); outptr += 4; } if (num_cols & 1) { - r = GETJSAMPLE(*inptr0); - g = GETJSAMPLE(*inptr1); - b = GETJSAMPLE(*inptr2); + r = *inptr0; + g = *inptr1; + b = *inptr2; rgb = PACK_SHORT_565(r, g, b); *(INT16 *)outptr = (INT16)rgb; } @@ -259,24 +259,24 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; if (PACK_NEED_ALIGNMENT(outptr)) { - r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)]; - g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)]; - b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)]; + r = range_limit[DITHER_565_R(*inptr0++, d0)]; + g = range_limit[DITHER_565_G(*inptr1++, d0)]; + b = range_limit[DITHER_565_B(*inptr2++, d0)]; rgb = PACK_SHORT_565(r, g, b); *(INT16 *)outptr = (INT16)rgb; outptr += 2; num_cols--; } for (col = 0; col < (num_cols >> 1); col++) { - r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)]; - g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)]; - b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)]; + r = range_limit[DITHER_565_R(*inptr0++, d0)]; + g = range_limit[DITHER_565_G(*inptr1++, d0)]; + b = range_limit[DITHER_565_B(*inptr2++, d0)]; d0 = DITHER_ROTATE(d0); rgb = PACK_SHORT_565(r, g, b); - r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)]; - g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)]; - b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)]; + r = range_limit[DITHER_565_R(*inptr0++, d0)]; + g = range_limit[DITHER_565_G(*inptr1++, d0)]; + b = range_limit[DITHER_565_B(*inptr2++, d0)]; d0 = DITHER_ROTATE(d0); rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); @@ -284,9 +284,9 @@ rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr += 4; } if (num_cols & 1) { - r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)]; - g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)]; - b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)]; + r = range_limit[DITHER_565_R(*inptr0, d0)]; + g = range_limit[DITHER_565_G(*inptr1, d0)]; + b = range_limit[DITHER_565_B(*inptr2, d0)]; rgb = PACK_SHORT_565(r, g, b); *(INT16 *)outptr = (INT16)rgb; } diff --git a/3rdparty/libjpeg-turbo/src/jdcolext.c b/3rdparty/libjpeg-turbo/src/jdcolext.c index 72a530107036..863c7a2fbc76 100644 --- a/3rdparty/libjpeg-turbo/src/jdcolext.c +++ b/3rdparty/libjpeg-turbo/src/jdcolext.c @@ -53,9 +53,9 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - y = GETJSAMPLE(inptr0[col]); - cb = GETJSAMPLE(inptr1[col]); - cr = GETJSAMPLE(inptr2[col]); + y = inptr0[col]; + cb = inptr1[col]; + cr = inptr2[col]; /* Range-limiting is essential due to noise introduced by DCT losses. */ outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[RGB_GREEN] = range_limit[y + @@ -93,7 +93,6 @@ gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, inptr = input_buf[0][input_row++]; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - /* We can dispense with GETJSAMPLE() here */ outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; /* Set unused byte to 0xFF so it can be interpreted as an opaque */ /* alpha channel value */ @@ -128,7 +127,6 @@ rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - /* We can dispense with GETJSAMPLE() here */ outptr[RGB_RED] = inptr0[col]; outptr[RGB_GREEN] = inptr1[col]; outptr[RGB_BLUE] = inptr2[col]; diff --git a/3rdparty/libjpeg-turbo/src/jdcolor.c b/3rdparty/libjpeg-turbo/src/jdcolor.c index d3ae40c7da9a..8da2b4eaf2e9 100644 --- a/3rdparty/libjpeg-turbo/src/jdcolor.c +++ b/3rdparty/libjpeg-turbo/src/jdcolor.c @@ -341,9 +341,9 @@ rgb_gray_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); + r = inptr0[col]; + g = inptr1[col]; + b = inptr2[col]; /* Y */ outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] + ctab[b + B_Y_OFF]) >> SCALEBITS); @@ -550,9 +550,9 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - y = GETJSAMPLE(inptr0[col]); - cb = GETJSAMPLE(inptr1[col]); - cr = GETJSAMPLE(inptr2[col]); + y = inptr0[col]; + cb = inptr1[col]; + cr = inptr2[col]; /* Range-limiting is essential due to noise introduced by DCT losses. */ outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ @@ -560,7 +560,7 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, SCALEBITS)))]; outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ /* K passes through unchanged */ - outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ + outptr[3] = inptr3[col]; outptr += 4; } } diff --git a/3rdparty/libjpeg-turbo/src/jdhuff.c b/3rdparty/libjpeg-turbo/src/jdhuff.c index a1128178b0a9..f786c1054735 100644 --- a/3rdparty/libjpeg-turbo/src/jdhuff.c +++ b/3rdparty/libjpeg-turbo/src/jdhuff.c @@ -5,6 +5,7 @@ * Copyright (C) 1991-1997, Thomas G. Lane. * libjpeg-turbo Modifications: * Copyright (C) 2009-2011, 2016, 2018-2019, D. R. Commander. + * Copyright (C) 2018, Matthias Räncker. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -39,24 +40,6 @@ typedef struct { int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ } savable_state; -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest, src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest, src) \ - ((dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - typedef struct { struct jpeg_entropy_decoder pub; /* public fields */ @@ -325,7 +308,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state, bytes_in_buffer = cinfo->src->bytes_in_buffer; } bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); + c = *next_input_byte++; /* If it's 0xFF, check and discard stuffed zero byte */ if (c == 0xFF) { @@ -342,7 +325,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state, bytes_in_buffer = cinfo->src->bytes_in_buffer; } bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); + c = *next_input_byte++; } while (c == 0xFF); if (c == 0) { @@ -405,8 +388,8 @@ jpeg_fill_bit_buffer(bitread_working_state *state, #define GET_BYTE { \ register int c0, c1; \ - c0 = GETJOCTET(*buffer++); \ - c1 = GETJOCTET(*buffer); \ + c0 = *buffer++; \ + c1 = *buffer; \ /* Pre-execute most common case */ \ get_buffer = (get_buffer << 8) | c0; \ bits_left += 8; \ @@ -423,7 +406,7 @@ jpeg_fill_bit_buffer(bitread_working_state *state, } \ } -#if SIZEOF_SIZE_T == 8 || defined(_WIN64) +#if SIZEOF_SIZE_T == 8 || defined(_WIN64) || (defined(__x86_64__) && defined(__ILP32__)) /* Pre-fetch 48 bytes, because the holding register is 64-bit */ #define FILL_BIT_BUFFER_FAST \ @@ -557,6 +540,12 @@ process_restart(j_decompress_ptr cinfo) } +#if defined(__has_feature) +#if __has_feature(undefined_behavior_sanitizer) +__attribute__((no_sanitize("signed-integer-overflow"), + no_sanitize("unsigned-integer-overflow"))) +#endif +#endif LOCAL(boolean) decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { @@ -568,7 +557,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Load up working state */ BITREAD_LOAD_STATE(cinfo, entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); + state = entropy->saved; for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL; @@ -589,11 +578,15 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (entropy->dc_needed[blkn]) { /* Convert DC difference to actual value, update last_dc_val */ int ci = cinfo->MCU_membership[blkn]; - /* This is really just - * s += state.last_dc_val[ci]; - * It is written this way in order to shut up UBSan. + /* Certain malformed JPEG images produce repeated DC coefficient + * differences of 2047 or -2047, which causes state.last_dc_val[ci] to + * grow until it overflows or underflows a 32-bit signed integer. This + * behavior is, to the best of our understanding, innocuous, and it is + * unclear how to work around it without potentially affecting + * performance. Thus, we (hopefully temporarily) suppress UBSan integer + * overflow errors for this function. */ - s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]); + s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; if (block) { /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ @@ -653,7 +646,7 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Completed MCU, so update state */ BITREAD_SAVE_STATE(cinfo, entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); + entropy->saved = state; return TRUE; } @@ -671,7 +664,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Load up working state */ BITREAD_LOAD_STATE(cinfo, entropy->bitstate); buffer = (JOCTET *)br_state.next_input_byte; - ASSIGN_STATE(state, entropy->saved); + state = entropy->saved; for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL; @@ -688,7 +681,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (entropy->dc_needed[blkn]) { int ci = cinfo->MCU_membership[blkn]; - s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]); + s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; if (block) (*block)[0] = (JCOEF)s; @@ -740,7 +733,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) br_state.bytes_in_buffer -= (buffer - br_state.next_input_byte); br_state.next_input_byte = buffer; BITREAD_SAVE_STATE(cinfo, entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); + entropy->saved = state; return TRUE; } @@ -795,7 +788,8 @@ decode_mcu(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) } /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; + if (cinfo->restart_interval) + entropy->restarts_to_go--; return TRUE; } diff --git a/3rdparty/libjpeg-turbo/src/jdhuff.h b/3rdparty/libjpeg-turbo/src/jdhuff.h index 6a8d90f4027c..cfa0b7f55888 100644 --- a/3rdparty/libjpeg-turbo/src/jdhuff.h +++ b/3rdparty/libjpeg-turbo/src/jdhuff.h @@ -4,7 +4,8 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-1997, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2010-2011, 2015-2016, D. R. Commander. + * Copyright (C) 2010-2011, 2015-2016, 2021, D. R. Commander. + * Copyright (C) 2018, Matthias Räncker. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -78,6 +79,11 @@ EXTERN(void) jpeg_make_d_derived_tbl(j_decompress_ptr cinfo, boolean isDC, typedef size_t bit_buf_type; /* type of bit-extraction buffer */ #define BIT_BUF_SIZE 64 /* size of buffer in bits */ +#elif defined(__x86_64__) && defined(__ILP32__) + +typedef unsigned long long bit_buf_type; /* type of bit-extraction buffer */ +#define BIT_BUF_SIZE 64 /* size of buffer in bits */ + #else typedef unsigned long bit_buf_type; /* type of bit-extraction buffer */ @@ -228,7 +234,10 @@ slowlabel: \ s |= GET_BITS(1); \ nb++; \ } \ - s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \ + if (nb > 16) \ + s = 0; \ + else \ + s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \ } /* Out-of-line case for Huffman code fetching */ diff --git a/3rdparty/libjpeg-turbo/src/jdicc.c b/3rdparty/libjpeg-turbo/src/jdicc.c index 7224695816b0..a1a5b867ae2b 100644 --- a/3rdparty/libjpeg-turbo/src/jdicc.c +++ b/3rdparty/libjpeg-turbo/src/jdicc.c @@ -38,18 +38,18 @@ marker_is_icc(jpeg_saved_marker_ptr marker) marker->marker == ICC_MARKER && marker->data_length >= ICC_OVERHEAD_LEN && /* verify the identifying string */ - GETJOCTET(marker->data[0]) == 0x49 && - GETJOCTET(marker->data[1]) == 0x43 && - GETJOCTET(marker->data[2]) == 0x43 && - GETJOCTET(marker->data[3]) == 0x5F && - GETJOCTET(marker->data[4]) == 0x50 && - GETJOCTET(marker->data[5]) == 0x52 && - GETJOCTET(marker->data[6]) == 0x4F && - GETJOCTET(marker->data[7]) == 0x46 && - GETJOCTET(marker->data[8]) == 0x49 && - GETJOCTET(marker->data[9]) == 0x4C && - GETJOCTET(marker->data[10]) == 0x45 && - GETJOCTET(marker->data[11]) == 0x0; + marker->data[0] == 0x49 && + marker->data[1] == 0x43 && + marker->data[2] == 0x43 && + marker->data[3] == 0x5F && + marker->data[4] == 0x50 && + marker->data[5] == 0x52 && + marker->data[6] == 0x4F && + marker->data[7] == 0x46 && + marker->data[8] == 0x49 && + marker->data[9] == 0x4C && + marker->data[10] == 0x45 && + marker->data[11] == 0x0; } @@ -102,12 +102,12 @@ jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr, for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (marker_is_icc(marker)) { if (num_markers == 0) - num_markers = GETJOCTET(marker->data[13]); - else if (num_markers != GETJOCTET(marker->data[13])) { + num_markers = marker->data[13]; + else if (num_markers != marker->data[13]) { WARNMS(cinfo, JWRN_BOGUS_ICC); /* inconsistent num_markers fields */ return FALSE; } - seq_no = GETJOCTET(marker->data[12]); + seq_no = marker->data[12]; if (seq_no <= 0 || seq_no > num_markers) { WARNMS(cinfo, JWRN_BOGUS_ICC); /* bogus sequence number */ return FALSE; @@ -154,7 +154,7 @@ jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr, JOCTET FAR *src_ptr; JOCTET *dst_ptr; unsigned int length; - seq_no = GETJOCTET(marker->data[12]); + seq_no = marker->data[12]; dst_ptr = icc_data + data_offset[seq_no]; src_ptr = marker->data + ICC_OVERHEAD_LEN; length = data_length[seq_no]; diff --git a/3rdparty/libjpeg-turbo/src/jdmarker.c b/3rdparty/libjpeg-turbo/src/jdmarker.c index c9c7ef639947..b964c3a1a6ac 100644 --- a/3rdparty/libjpeg-turbo/src/jdmarker.c +++ b/3rdparty/libjpeg-turbo/src/jdmarker.c @@ -151,7 +151,7 @@ typedef my_marker_reader *my_marker_ptr; #define INPUT_BYTE(cinfo, V, action) \ MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \ bytes_in_buffer--; \ - V = GETJOCTET(*next_input_byte++); ) + V = *next_input_byte++; ) /* As above, but read two bytes interpreted as an unsigned 16-bit integer. * V should be declared unsigned int or perhaps JLONG. @@ -159,10 +159,10 @@ typedef my_marker_reader *my_marker_ptr; #define INPUT_2BYTES(cinfo, V, action) \ MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \ bytes_in_buffer--; \ - V = ((unsigned int)GETJOCTET(*next_input_byte++)) << 8; \ + V = ((unsigned int)(*next_input_byte++)) << 8; \ MAKE_BYTE_AVAIL(cinfo, action); \ bytes_in_buffer--; \ - V += GETJOCTET(*next_input_byte++); ) + V += *next_input_byte++; ) /* @@ -608,18 +608,18 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen, JLONG totallen = (JLONG)datalen + remaining; if (datalen >= APP0_DATA_LEN && - GETJOCTET(data[0]) == 0x4A && - GETJOCTET(data[1]) == 0x46 && - GETJOCTET(data[2]) == 0x49 && - GETJOCTET(data[3]) == 0x46 && - GETJOCTET(data[4]) == 0) { + data[0] == 0x4A && + data[1] == 0x46 && + data[2] == 0x49 && + data[3] == 0x46 && + data[4] == 0) { /* Found JFIF APP0 marker: save info */ cinfo->saw_JFIF_marker = TRUE; - cinfo->JFIF_major_version = GETJOCTET(data[5]); - cinfo->JFIF_minor_version = GETJOCTET(data[6]); - cinfo->density_unit = GETJOCTET(data[7]); - cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); - cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); + cinfo->JFIF_major_version = data[5]; + cinfo->JFIF_minor_version = data[6]; + cinfo->density_unit = data[7]; + cinfo->X_density = (data[8] << 8) + data[9]; + cinfo->Y_density = (data[10] << 8) + data[11]; /* Check version. * Major version must be 1, anything else signals an incompatible change. * (We used to treat this as an error, but now it's a nonfatal warning, @@ -634,24 +634,22 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen, cinfo->JFIF_major_version, cinfo->JFIF_minor_version, cinfo->X_density, cinfo->Y_density, cinfo->density_unit); /* Validate thumbnail dimensions and issue appropriate messages */ - if (GETJOCTET(data[12]) | GETJOCTET(data[13])) - TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, - GETJOCTET(data[12]), GETJOCTET(data[13])); + if (data[12] | data[13]) + TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, data[12], data[13]); totallen -= APP0_DATA_LEN; - if (totallen != - ((JLONG)GETJOCTET(data[12]) * (JLONG)GETJOCTET(data[13]) * (JLONG)3)) + if (totallen != ((JLONG)data[12] * (JLONG)data[13] * (JLONG)3)) TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int)totallen); } else if (datalen >= 6 && - GETJOCTET(data[0]) == 0x4A && - GETJOCTET(data[1]) == 0x46 && - GETJOCTET(data[2]) == 0x58 && - GETJOCTET(data[3]) == 0x58 && - GETJOCTET(data[4]) == 0) { + data[0] == 0x4A && + data[1] == 0x46 && + data[2] == 0x58 && + data[3] == 0x58 && + data[4] == 0) { /* Found JFIF "JFXX" extension APP0 marker */ /* The library doesn't actually do anything with these, * but we try to produce a helpful trace message. */ - switch (GETJOCTET(data[5])) { + switch (data[5]) { case 0x10: TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int)totallen); break; @@ -662,8 +660,7 @@ examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen, TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int)totallen); break; default: - TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, - GETJOCTET(data[5]), (int)totallen); + TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, data[5], (int)totallen); break; } } else { @@ -684,16 +681,16 @@ examine_app14(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen, unsigned int version, flags0, flags1, transform; if (datalen >= APP14_DATA_LEN && - GETJOCTET(data[0]) == 0x41 && - GETJOCTET(data[1]) == 0x64 && - GETJOCTET(data[2]) == 0x6F && - GETJOCTET(data[3]) == 0x62 && - GETJOCTET(data[4]) == 0x65) { + data[0] == 0x41 && + data[1] == 0x64 && + data[2] == 0x6F && + data[3] == 0x62 && + data[4] == 0x65) { /* Found Adobe APP14 marker */ - version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]); - flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]); - flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]); - transform = GETJOCTET(data[11]); + version = (data[5] << 8) + data[6]; + flags0 = (data[7] << 8) + data[8]; + flags1 = (data[9] << 8) + data[10]; + transform = data[11]; TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); cinfo->saw_Adobe_marker = TRUE; cinfo->Adobe_transform = (UINT8)transform; diff --git a/3rdparty/libjpeg-turbo/src/jdmaster.c b/3rdparty/libjpeg-turbo/src/jdmaster.c index b20906438e49..cbc8774b1f2b 100644 --- a/3rdparty/libjpeg-turbo/src/jdmaster.c +++ b/3rdparty/libjpeg-turbo/src/jdmaster.c @@ -5,7 +5,7 @@ * Copyright (C) 1991-1997, Thomas G. Lane. * Modified 2002-2009 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2009-2011, 2016, D. R. Commander. + * Copyright (C) 2009-2011, 2016, 2019, D. R. Commander. * Copyright (C) 2013, Linaro Limited. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg @@ -22,7 +22,6 @@ #include "jpeglib.h" #include "jpegcomp.h" #include "jdmaster.h" -#include "jsimd.h" /* @@ -70,17 +69,6 @@ use_merged_upsample(j_decompress_ptr cinfo) cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size || cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size) return FALSE; -#ifdef WITH_SIMD - /* If YCbCr-to-RGB color conversion is SIMD-accelerated but merged upsampling - isn't, then disabling merged upsampling is likely to be faster when - decompressing YCbCr JPEG images. */ - if (!jsimd_can_h2v2_merged_upsample() && !jsimd_can_h2v1_merged_upsample() && - jsimd_can_ycc_rgb() && cinfo->jpeg_color_space == JCS_YCbCr && - (cinfo->out_color_space == JCS_RGB || - (cinfo->out_color_space >= JCS_EXT_RGB && - cinfo->out_color_space <= JCS_EXT_ARGB))) - return FALSE; -#endif /* ??? also need to test for upsample-time rescaling, when & if supported */ return TRUE; /* by golly, it'll work... */ #else @@ -580,6 +568,7 @@ master_selection(j_decompress_ptr cinfo) */ cinfo->master->first_iMCU_col = 0; cinfo->master->last_iMCU_col = cinfo->MCUs_per_row - 1; + cinfo->master->last_good_iMCU_row = 0; #ifdef D_MULTISCAN_FILES_SUPPORTED /* If jpeg_start_decompress will read the whole file, initialize diff --git a/3rdparty/libjpeg-turbo/src/jdmrg565.c b/3rdparty/libjpeg-turbo/src/jdmrg565.c index 53f1e1670006..980a4e216e4d 100644 --- a/3rdparty/libjpeg-turbo/src/jdmrg565.c +++ b/3rdparty/libjpeg-turbo/src/jdmrg565.c @@ -43,20 +43,20 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* Loop for each pair of output pixels */ for (col = cinfo->output_width >> 1; col > 0; col--) { /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + cb = *inptr1++; + cr = *inptr2++; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; /* Fetch 2 Y values and emit 2 pixels */ - y = GETJSAMPLE(*inptr0++); + y = *inptr0++; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr0++); + y = *inptr0++; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; @@ -68,12 +68,12 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + cb = *inptr1; + cr = *inptr2; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); + y = *inptr0; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; @@ -115,21 +115,21 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo, /* Loop for each pair of output pixels */ for (col = cinfo->output_width >> 1; col > 0; col--) { /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + cb = *inptr1++; + cr = *inptr2++; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; /* Fetch 2 Y values and emit 2 pixels */ - y = GETJSAMPLE(*inptr0++); + y = *inptr0++; r = range_limit[DITHER_565_R(y + cred, d0)]; g = range_limit[DITHER_565_G(y + cgreen, d0)]; b = range_limit[DITHER_565_B(y + cblue, d0)]; d0 = DITHER_ROTATE(d0); rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr0++); + y = *inptr0++; r = range_limit[DITHER_565_R(y + cred, d0)]; g = range_limit[DITHER_565_G(y + cgreen, d0)]; b = range_limit[DITHER_565_B(y + cblue, d0)]; @@ -142,12 +142,12 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo, /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + cb = *inptr1; + cr = *inptr2; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); + y = *inptr0; r = range_limit[DITHER_565_R(y + cred, d0)]; g = range_limit[DITHER_565_G(y + cgreen, d0)]; b = range_limit[DITHER_565_B(y + cblue, d0)]; @@ -189,20 +189,20 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* Loop for each group of output pixels */ for (col = cinfo->output_width >> 1; col > 0; col--) { /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + cb = *inptr1++; + cr = *inptr2++; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; /* Fetch 4 Y values and emit 4 pixels */ - y = GETJSAMPLE(*inptr00++); + y = *inptr00++; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr00++); + y = *inptr00++; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; @@ -211,13 +211,13 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, WRITE_TWO_PIXELS(outptr0, rgb); outptr0 += 4; - y = GETJSAMPLE(*inptr01++); + y = *inptr01++; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr01++); + y = *inptr01++; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; @@ -229,20 +229,20 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + cb = *inptr1; + cr = *inptr2; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr00); + y = *inptr00; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; rgb = PACK_SHORT_565(r, g, b); *(INT16 *)outptr0 = (INT16)rgb; - y = GETJSAMPLE(*inptr01); + y = *inptr01; r = range_limit[y + cred]; g = range_limit[y + cgreen]; b = range_limit[y + cblue]; @@ -287,21 +287,21 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo, /* Loop for each group of output pixels */ for (col = cinfo->output_width >> 1; col > 0; col--) { /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + cb = *inptr1++; + cr = *inptr2++; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; /* Fetch 4 Y values and emit 4 pixels */ - y = GETJSAMPLE(*inptr00++); + y = *inptr00++; r = range_limit[DITHER_565_R(y + cred, d0)]; g = range_limit[DITHER_565_G(y + cgreen, d0)]; b = range_limit[DITHER_565_B(y + cblue, d0)]; d0 = DITHER_ROTATE(d0); rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr00++); + y = *inptr00++; r = range_limit[DITHER_565_R(y + cred, d0)]; g = range_limit[DITHER_565_G(y + cgreen, d0)]; b = range_limit[DITHER_565_B(y + cblue, d0)]; @@ -311,14 +311,14 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo, WRITE_TWO_PIXELS(outptr0, rgb); outptr0 += 4; - y = GETJSAMPLE(*inptr01++); + y = *inptr01++; r = range_limit[DITHER_565_R(y + cred, d1)]; g = range_limit[DITHER_565_G(y + cgreen, d1)]; b = range_limit[DITHER_565_B(y + cblue, d1)]; d1 = DITHER_ROTATE(d1); rgb = PACK_SHORT_565(r, g, b); - y = GETJSAMPLE(*inptr01++); + y = *inptr01++; r = range_limit[DITHER_565_R(y + cred, d1)]; g = range_limit[DITHER_565_G(y + cgreen, d1)]; b = range_limit[DITHER_565_B(y + cblue, d1)]; @@ -331,20 +331,20 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo, /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + cb = *inptr1; + cr = *inptr2; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr00); + y = *inptr00; r = range_limit[DITHER_565_R(y + cred, d0)]; g = range_limit[DITHER_565_G(y + cgreen, d0)]; b = range_limit[DITHER_565_B(y + cblue, d0)]; rgb = PACK_SHORT_565(r, g, b); *(INT16 *)outptr0 = (INT16)rgb; - y = GETJSAMPLE(*inptr01); + y = *inptr01; r = range_limit[DITHER_565_R(y + cred, d1)]; g = range_limit[DITHER_565_G(y + cgreen, d1)]; b = range_limit[DITHER_565_B(y + cblue, d1)]; diff --git a/3rdparty/libjpeg-turbo/src/jdmrgext.c b/3rdparty/libjpeg-turbo/src/jdmrgext.c index c9a44d8219c2..9bf4f1a307f3 100644 --- a/3rdparty/libjpeg-turbo/src/jdmrgext.c +++ b/3rdparty/libjpeg-turbo/src/jdmrgext.c @@ -46,13 +46,13 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* Loop for each pair of output pixels */ for (col = cinfo->output_width >> 1; col > 0; col--) { /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + cb = *inptr1++; + cr = *inptr2++; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; /* Fetch 2 Y values and emit 2 pixels */ - y = GETJSAMPLE(*inptr0++); + y = *inptr0++; outptr[RGB_RED] = range_limit[y + cred]; outptr[RGB_GREEN] = range_limit[y + cgreen]; outptr[RGB_BLUE] = range_limit[y + cblue]; @@ -60,7 +60,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr[RGB_ALPHA] = 0xFF; #endif outptr += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr0++); + y = *inptr0++; outptr[RGB_RED] = range_limit[y + cred]; outptr[RGB_GREEN] = range_limit[y + cgreen]; outptr[RGB_BLUE] = range_limit[y + cblue]; @@ -71,12 +71,12 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, } /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + cb = *inptr1; + cr = *inptr2; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); + y = *inptr0; outptr[RGB_RED] = range_limit[y + cred]; outptr[RGB_GREEN] = range_limit[y + cgreen]; outptr[RGB_BLUE] = range_limit[y + cblue]; @@ -120,13 +120,13 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* Loop for each group of output pixels */ for (col = cinfo->output_width >> 1; col > 0; col--) { /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); + cb = *inptr1++; + cr = *inptr2++; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; /* Fetch 4 Y values and emit 4 pixels */ - y = GETJSAMPLE(*inptr00++); + y = *inptr00++; outptr0[RGB_RED] = range_limit[y + cred]; outptr0[RGB_GREEN] = range_limit[y + cgreen]; outptr0[RGB_BLUE] = range_limit[y + cblue]; @@ -134,7 +134,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr0[RGB_ALPHA] = 0xFF; #endif outptr0 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr00++); + y = *inptr00++; outptr0[RGB_RED] = range_limit[y + cred]; outptr0[RGB_GREEN] = range_limit[y + cgreen]; outptr0[RGB_BLUE] = range_limit[y + cblue]; @@ -142,7 +142,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr0[RGB_ALPHA] = 0xFF; #endif outptr0 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr01++); + y = *inptr01++; outptr1[RGB_RED] = range_limit[y + cred]; outptr1[RGB_GREEN] = range_limit[y + cgreen]; outptr1[RGB_BLUE] = range_limit[y + cblue]; @@ -150,7 +150,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, outptr1[RGB_ALPHA] = 0xFF; #endif outptr1 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr01++); + y = *inptr01++; outptr1[RGB_RED] = range_limit[y + cred]; outptr1[RGB_GREEN] = range_limit[y + cgreen]; outptr1[RGB_BLUE] = range_limit[y + cblue]; @@ -161,19 +161,19 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, } /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); + cb = *inptr1; + cr = *inptr2; cred = Crrtab[cr]; cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr00); + y = *inptr00; outptr0[RGB_RED] = range_limit[y + cred]; outptr0[RGB_GREEN] = range_limit[y + cgreen]; outptr0[RGB_BLUE] = range_limit[y + cblue]; #ifdef RGB_ALPHA outptr0[RGB_ALPHA] = 0xFF; #endif - y = GETJSAMPLE(*inptr01); + y = *inptr01; outptr1[RGB_RED] = range_limit[y + cred]; outptr1[RGB_GREEN] = range_limit[y + cgreen]; outptr1[RGB_BLUE] = range_limit[y + cblue]; diff --git a/3rdparty/libjpeg-turbo/src/jdphuff.c b/3rdparty/libjpeg-turbo/src/jdphuff.c index 9e82636bbd12..c6d82ca14b8c 100644 --- a/3rdparty/libjpeg-turbo/src/jdphuff.c +++ b/3rdparty/libjpeg-turbo/src/jdphuff.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1995-1997, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2015-2016, 2018, D. R. Commander. + * Copyright (C) 2015-2016, 2018-2021, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -41,25 +41,6 @@ typedef struct { int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ } savable_state; -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest, src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest, src) \ - ((dest).EOBRUN = (src).EOBRUN, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - typedef struct { struct jpeg_entropy_decoder pub; /* public fields */ @@ -102,7 +83,7 @@ start_pass_phuff_decoder(j_decompress_ptr cinfo) boolean is_DC_band, bad; int ci, coefi, tbl; d_derived_tbl **pdtbl; - int *coef_bit_ptr; + int *coef_bit_ptr, *prev_coef_bit_ptr; jpeg_component_info *compptr; is_DC_band = (cinfo->Ss == 0); @@ -143,8 +124,15 @@ start_pass_phuff_decoder(j_decompress_ptr cinfo) for (ci = 0; ci < cinfo->comps_in_scan; ci++) { int cindex = cinfo->cur_comp_info[ci]->component_index; coef_bit_ptr = &cinfo->coef_bits[cindex][0]; + prev_coef_bit_ptr = &cinfo->coef_bits[cindex + cinfo->num_components][0]; if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); + for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) { + if (cinfo->input_scan_number > 1) + prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi]; + else + prev_coef_bit_ptr[coefi] = 0; + } for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; if (cinfo->Ah != expected) @@ -323,7 +311,7 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Load up working state */ BITREAD_LOAD_STATE(cinfo, entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); + state = entropy->saved; /* Outer loop handles each block in the MCU */ @@ -356,11 +344,12 @@ decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Completed MCU, so update state */ BITREAD_SAVE_STATE(cinfo, entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); + entropy->saved = state; } /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; + if (cinfo->restart_interval) + entropy->restarts_to_go--; return TRUE; } @@ -444,7 +433,8 @@ decode_mcu_AC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) } /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; + if (cinfo->restart_interval) + entropy->restarts_to_go--; return TRUE; } @@ -495,7 +485,8 @@ decode_mcu_DC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) BITREAD_SAVE_STATE(cinfo, entropy->bitstate); /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; + if (cinfo->restart_interval) + entropy->restarts_to_go--; return TRUE; } @@ -638,7 +629,8 @@ decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) } /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; + if (cinfo->restart_interval) + entropy->restarts_to_go--; return TRUE; @@ -676,7 +668,7 @@ jinit_phuff_decoder(j_decompress_ptr cinfo) /* Create progression status table */ cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, - cinfo->num_components * DCTSIZE2 * + cinfo->num_components * 2 * DCTSIZE2 * sizeof(int)); coef_bit_ptr = &cinfo->coef_bits[0][0]; for (ci = 0; ci < cinfo->num_components; ci++) diff --git a/3rdparty/libjpeg-turbo/src/jdsample.c b/3rdparty/libjpeg-turbo/src/jdsample.c index 50a68b301318..eaad72a03089 100644 --- a/3rdparty/libjpeg-turbo/src/jdsample.c +++ b/3rdparty/libjpeg-turbo/src/jdsample.c @@ -8,7 +8,7 @@ * Copyright (C) 2010, 2015-2016, D. R. Commander. * Copyright (C) 2014, MIPS Technologies, Inc., California. * Copyright (C) 2015, Google, Inc. - * Copyright (C) 2019, Arm Limited. + * Copyright (C) 2019-2020, Arm Limited. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -177,7 +177,7 @@ int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, outptr = output_data[outrow]; outend = outptr + cinfo->output_width; while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ + invalue = *inptr++; for (h = h_expand; h > 0; h--) { *outptr++ = invalue; } @@ -213,7 +213,7 @@ h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, outptr = output_data[inrow]; outend = outptr + cinfo->output_width; while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ + invalue = *inptr++; *outptr++ = invalue; *outptr++ = invalue; } @@ -242,7 +242,7 @@ h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, outptr = output_data[outrow]; outend = outptr + cinfo->output_width; while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ + invalue = *inptr++; *outptr++ = invalue; *outptr++ = invalue; } @@ -283,20 +283,20 @@ h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, inptr = input_data[inrow]; outptr = output_data[inrow]; /* Special case for first column */ - invalue = GETJSAMPLE(*inptr++); + invalue = *inptr++; *outptr++ = (JSAMPLE)invalue; - *outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); + *outptr++ = (JSAMPLE)((invalue * 3 + inptr[0] + 2) >> 2); for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ - invalue = GETJSAMPLE(*inptr++) * 3; - *outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); - *outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(*inptr) + 2) >> 2); + invalue = (*inptr++) * 3; + *outptr++ = (JSAMPLE)((invalue + inptr[-2] + 1) >> 2); + *outptr++ = (JSAMPLE)((invalue + inptr[0] + 2) >> 2); } /* Special case for last column */ - invalue = GETJSAMPLE(*inptr); - *outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); + invalue = *inptr; + *outptr++ = (JSAMPLE)((invalue * 3 + inptr[-1] + 1) >> 2); *outptr++ = (JSAMPLE)invalue; } } @@ -338,7 +338,7 @@ h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, outptr = output_data[outrow++]; for (colctr = 0; colctr < compptr->downsampled_width; colctr++) { - thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + thiscolsum = (*inptr0++) * 3 + (*inptr1++); *outptr++ = (JSAMPLE)((thiscolsum + bias) >> 2); } } @@ -381,8 +381,8 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, outptr = output_data[outrow++]; /* Special case for first column */ - thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); - nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + thiscolsum = (*inptr0++) * 3 + (*inptr1++); + nextcolsum = (*inptr0++) * 3 + (*inptr1++); *outptr++ = (JSAMPLE)((thiscolsum * 4 + 8) >> 4); *outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4); lastcolsum = thiscolsum; thiscolsum = nextcolsum; @@ -390,7 +390,7 @@ h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ - nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); + nextcolsum = (*inptr0++) * 3 + (*inptr1++); *outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4); *outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4); lastcolsum = thiscolsum; thiscolsum = nextcolsum; @@ -477,7 +477,13 @@ jinit_upsampler(j_decompress_ptr cinfo) } else if (h_in_group == h_out_group && v_in_group * 2 == v_out_group && do_fancy) { /* Non-fancy upsampling is handled by the generic method */ - upsample->methods[ci] = h1v2_fancy_upsample; +#if defined(__arm__) || defined(__aarch64__) || \ + defined(_M_ARM) || defined(_M_ARM64) + if (jsimd_can_h1v2_fancy_upsample()) + upsample->methods[ci] = jsimd_h1v2_fancy_upsample; + else +#endif + upsample->methods[ci] = h1v2_fancy_upsample; upsample->pub.need_context_rows = TRUE; } else if (h_in_group * 2 == h_out_group && v_in_group * 2 == v_out_group) { diff --git a/3rdparty/libjpeg-turbo/src/jerror.h b/3rdparty/libjpeg-turbo/src/jerror.h index 933a3690fdf4..4476df2c934b 100644 --- a/3rdparty/libjpeg-turbo/src/jerror.h +++ b/3rdparty/libjpeg-turbo/src/jerror.h @@ -207,6 +207,10 @@ JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") #endif #endif JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker") +#if JPEG_LIB_VERSION < 70 +JMESSAGE(JERR_BAD_DROP_SAMPLING, + "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c") +#endif #ifdef JMAKE_ENUM_LIST @@ -252,6 +256,15 @@ JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker") (cinfo)->err->msg_parm.i[2] = (p3), \ (cinfo)->err->msg_parm.i[3] = (p4), \ (*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo))) +#define ERREXIT6(cinfo, code, p1, p2, p3, p4, p5, p6) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (cinfo)->err->msg_parm.i[4] = (p5), \ + (cinfo)->err->msg_parm.i[5] = (p6), \ + (*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo))) #define ERREXITS(cinfo, code, str) \ ((cinfo)->err->msg_code = (code), \ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ diff --git a/3rdparty/libjpeg-turbo/src/jidctint.c b/3rdparty/libjpeg-turbo/src/jidctint.c index 50f385da3329..bb0874801920 100644 --- a/3rdparty/libjpeg-turbo/src/jidctint.c +++ b/3rdparty/libjpeg-turbo/src/jidctint.c @@ -3,7 +3,7 @@ * * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-1998, Thomas G. Lane. - * Modification developed 2002-2009 by Guido Vollbeding. + * Modification developed 2002-2018 by Guido Vollbeding. * libjpeg-turbo Modifications: * Copyright (C) 2015, 2020, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg @@ -417,7 +417,7 @@ jpeg_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr, /* * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 7x7 output block. + * producing a reduced-size 7x7 output block. * * Optimized algorithm with 12 multiplications in the 1-D kernel. * cK represents sqrt(2) * cos(K*pi/14). @@ -1258,7 +1258,7 @@ jpeg_idct_10x10(j_decompress_ptr cinfo, jpeg_component_info *compptr, /* * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 11x11 output block. + * producing an 11x11 output block. * * Optimized algorithm with 24 multiplications in the 1-D kernel. * cK represents sqrt(2) * cos(K*pi/22). @@ -2398,7 +2398,7 @@ jpeg_idct_16x16(j_decompress_ptr cinfo, jpeg_component_info *compptr, tmp0 = DEQUANTIZE(inptr[DCTSIZE * 0], quantptr[DCTSIZE * 0]); tmp0 = LEFT_SHIFT(tmp0, CONST_BITS); /* Add fudge factor here for final descale. */ - tmp0 += 1 << (CONST_BITS - PASS1_BITS - 1); + tmp0 += ONE << (CONST_BITS - PASS1_BITS - 1); z1 = DEQUANTIZE(inptr[DCTSIZE * 4], quantptr[DCTSIZE * 4]); tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */ diff --git a/3rdparty/libjpeg-turbo/src/jmorecfg.h b/3rdparty/libjpeg-turbo/src/jmorecfg.h index aa29f0f9f13e..fb3a9cf411cc 100644 --- a/3rdparty/libjpeg-turbo/src/jmorecfg.h +++ b/3rdparty/libjpeg-turbo/src/jmorecfg.h @@ -43,25 +43,11 @@ #if BITS_IN_JSAMPLE == 8 /* JSAMPLE should be the smallest type that will hold the values 0..255. - * You can use a signed char by having GETJSAMPLE mask it with 0xFF. */ -#ifdef HAVE_UNSIGNED_CHAR - typedef unsigned char JSAMPLE; #define GETJSAMPLE(value) ((int)(value)) -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JSAMPLE; -#ifdef __CHAR_UNSIGNED__ -#define GETJSAMPLE(value) ((int)(value)) -#else -#define GETJSAMPLE(value) ((int)(value) & 0xFF) -#endif /* __CHAR_UNSIGNED__ */ - -#endif /* HAVE_UNSIGNED_CHAR */ - #define MAXJSAMPLE 255 #define CENTERJSAMPLE 128 @@ -97,22 +83,9 @@ typedef short JCOEF; * managers, this is also the data type passed to fread/fwrite. */ -#ifdef HAVE_UNSIGNED_CHAR - typedef unsigned char JOCTET; #define GETJOCTET(value) (value) -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JOCTET; -#ifdef __CHAR_UNSIGNED__ -#define GETJOCTET(value) (value) -#else -#define GETJOCTET(value) ((value) & 0xFF) -#endif /* __CHAR_UNSIGNED__ */ - -#endif /* HAVE_UNSIGNED_CHAR */ - /* These typedefs are used for various table entries and so forth. * They must be at least as wide as specified; but making them too big @@ -123,15 +96,7 @@ typedef char JOCTET; /* UINT8 must hold at least the values 0..255. */ -#ifdef HAVE_UNSIGNED_CHAR typedef unsigned char UINT8; -#else /* not HAVE_UNSIGNED_CHAR */ -#ifdef __CHAR_UNSIGNED__ -typedef char UINT8; -#else /* not __CHAR_UNSIGNED__ */ -typedef short UINT8; -#endif /* __CHAR_UNSIGNED__ */ -#endif /* HAVE_UNSIGNED_CHAR */ /* UINT16 must hold at least the values 0..65535. */ diff --git a/3rdparty/libjpeg-turbo/src/jpegint.h b/3rdparty/libjpeg-turbo/src/jpegint.h index ad36ca8b5605..195fbcb9b675 100644 --- a/3rdparty/libjpeg-turbo/src/jpegint.h +++ b/3rdparty/libjpeg-turbo/src/jpegint.h @@ -5,7 +5,7 @@ * Copyright (C) 1991-1997, Thomas G. Lane. * Modified 1997-2009 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2015-2016, D. R. Commander. + * Copyright (C) 2015-2016, 2019, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. @@ -158,6 +158,9 @@ struct jpeg_decomp_master { JDIMENSION first_MCU_col[MAX_COMPONENTS]; JDIMENSION last_MCU_col[MAX_COMPONENTS]; boolean jinit_upsampler_no_alloc; + + /* Last iMCU row that was successfully decoded */ + JDIMENSION last_good_iMCU_row; }; /* Input control module */ diff --git a/3rdparty/libjpeg-turbo/src/jquant1.c b/3rdparty/libjpeg-turbo/src/jquant1.c index 40bbb28cc7f6..73b83e16e5cc 100644 --- a/3rdparty/libjpeg-turbo/src/jquant1.c +++ b/3rdparty/libjpeg-turbo/src/jquant1.c @@ -479,7 +479,7 @@ color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf, for (col = width; col > 0; col--) { pixcode = 0; for (ci = 0; ci < nc; ci++) { - pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); + pixcode += colorindex[ci][*ptrin++]; } *ptrout++ = (JSAMPLE)pixcode; } @@ -506,9 +506,9 @@ color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf, ptrin = input_buf[row]; ptrout = output_buf[row]; for (col = width; col > 0; col--) { - pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); - pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); - pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); + pixcode = colorindex0[*ptrin++]; + pixcode += colorindex1[*ptrin++]; + pixcode += colorindex2[*ptrin++]; *ptrout++ = (JSAMPLE)pixcode; } } @@ -552,7 +552,7 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, * required amount of padding. */ *output_ptr += - colorindex_ci[GETJSAMPLE(*input_ptr) + dither[col_index]]; + colorindex_ci[*input_ptr + dither[col_index]]; input_ptr += nc; output_ptr++; col_index = (col_index + 1) & ODITHER_MASK; @@ -595,12 +595,9 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, col_index = 0; for (col = width; col > 0; col--) { - pixcode = - GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + dither0[col_index]]); - pixcode += - GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + dither1[col_index]]); - pixcode += - GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + dither2[col_index]]); + pixcode = colorindex0[(*input_ptr++) + dither0[col_index]]; + pixcode += colorindex1[(*input_ptr++) + dither1[col_index]]; + pixcode += colorindex2[(*input_ptr++) + dither2[col_index]]; *output_ptr++ = (JSAMPLE)pixcode; col_index = (col_index + 1) & ODITHER_MASK; } @@ -677,15 +674,15 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, * The maximum error is +- MAXJSAMPLE; this sets the required size * of the range_limit array. */ - cur += GETJSAMPLE(*input_ptr); - cur = GETJSAMPLE(range_limit[cur]); + cur += *input_ptr; + cur = range_limit[cur]; /* Select output value, accumulate into output code for this pixel */ - pixcode = GETJSAMPLE(colorindex_ci[cur]); + pixcode = colorindex_ci[cur]; *output_ptr += (JSAMPLE)pixcode; /* Compute actual representation error at this pixel */ /* Note: we can do this even though we don't have the final */ /* pixel code, because the colormap is orthogonal. */ - cur -= GETJSAMPLE(colormap_ci[pixcode]); + cur -= colormap_ci[pixcode]; /* Compute error fractions to be propagated to adjacent pixels. * Add these into the running sums, and simultaneously shift the * next-line error sums left by 1 column. diff --git a/3rdparty/libjpeg-turbo/src/jquant2.c b/3rdparty/libjpeg-turbo/src/jquant2.c index 6570613bb9f2..44efb18cadf1 100644 --- a/3rdparty/libjpeg-turbo/src/jquant2.c +++ b/3rdparty/libjpeg-turbo/src/jquant2.c @@ -215,9 +215,9 @@ prescan_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf, ptr = input_buf[row]; for (col = width; col > 0; col--) { /* get pixel value and index into the histogram */ - histp = &histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] - [GETJSAMPLE(ptr[1]) >> C1_SHIFT] - [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; + histp = &histogram[ptr[0] >> C0_SHIFT] + [ptr[1] >> C1_SHIFT] + [ptr[2] >> C2_SHIFT]; /* increment, check for overflow and undo increment if so. */ if (++(*histp) <= 0) (*histp)--; @@ -665,7 +665,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, for (i = 0; i < numcolors; i++) { /* We compute the squared-c0-distance term, then add in the other two. */ - x = GETJSAMPLE(cinfo->colormap[0][i]); + x = cinfo->colormap[0][i]; if (x < minc0) { tdist = (x - minc0) * C0_SCALE; min_dist = tdist * tdist; @@ -688,7 +688,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, } } - x = GETJSAMPLE(cinfo->colormap[1][i]); + x = cinfo->colormap[1][i]; if (x < minc1) { tdist = (x - minc1) * C1_SCALE; min_dist += tdist * tdist; @@ -710,7 +710,7 @@ find_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, } } - x = GETJSAMPLE(cinfo->colormap[2][i]); + x = cinfo->colormap[2][i]; if (x < minc2) { tdist = (x - minc2) * C2_SCALE; min_dist += tdist * tdist; @@ -788,13 +788,13 @@ find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, #define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) for (i = 0; i < numcolors; i++) { - icolor = GETJSAMPLE(colorlist[i]); + icolor = colorlist[i]; /* Compute (square of) distance from minc0/c1/c2 to this color */ - inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; + inc0 = (minc0 - cinfo->colormap[0][icolor]) * C0_SCALE; dist0 = inc0 * inc0; - inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; + inc1 = (minc1 - cinfo->colormap[1][icolor]) * C1_SCALE; dist0 += inc1 * inc1; - inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; + inc2 = (minc2 - cinfo->colormap[2][icolor]) * C2_SCALE; dist0 += inc2 * inc2; /* Form the initial difference increments */ inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; @@ -879,7 +879,7 @@ fill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2) for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { cachep = &histogram[c0 + ic0][c1 + ic1][c2]; for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { - *cachep++ = (histcell)(GETJSAMPLE(*cptr++) + 1); + *cachep++ = (histcell)((*cptr++) + 1); } } } @@ -909,9 +909,9 @@ pass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, outptr = output_buf[row]; for (col = width; col > 0; col--) { /* get pixel value and index into the cache */ - c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; - c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; - c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; + c0 = (*inptr++) >> C0_SHIFT; + c1 = (*inptr++) >> C1_SHIFT; + c2 = (*inptr++) >> C2_SHIFT; cachep = &histogram[c0][c1][c2]; /* If we have not seen this color before, find nearest colormap entry */ /* and update the cache */ @@ -996,12 +996,12 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, * The maximum error is +- MAXJSAMPLE (or less with error limiting); * this sets the required size of the range_limit array. */ - cur0 += GETJSAMPLE(inptr[0]); - cur1 += GETJSAMPLE(inptr[1]); - cur2 += GETJSAMPLE(inptr[2]); - cur0 = GETJSAMPLE(range_limit[cur0]); - cur1 = GETJSAMPLE(range_limit[cur1]); - cur2 = GETJSAMPLE(range_limit[cur2]); + cur0 += inptr[0]; + cur1 += inptr[1]; + cur2 += inptr[2]; + cur0 = range_limit[cur0]; + cur1 = range_limit[cur1]; + cur2 = range_limit[cur2]; /* Index into the cache with adjusted pixel value */ cachep = &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT]; @@ -1015,9 +1015,9 @@ pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, register int pixcode = *cachep - 1; *outptr = (JSAMPLE)pixcode; /* Compute representation error for this pixel */ - cur0 -= GETJSAMPLE(colormap0[pixcode]); - cur1 -= GETJSAMPLE(colormap1[pixcode]); - cur2 -= GETJSAMPLE(colormap2[pixcode]); + cur0 -= colormap0[pixcode]; + cur1 -= colormap1[pixcode]; + cur2 -= colormap2[pixcode]; } /* Compute error fractions to be propagated to adjacent pixels. * Add these into the running sums, and simultaneously shift the diff --git a/3rdparty/libjpeg-turbo/src/jsimd.h b/3rdparty/libjpeg-turbo/src/jsimd.h index 51e2b8c89de3..6c203655ef84 100644 --- a/3rdparty/libjpeg-turbo/src/jsimd.h +++ b/3rdparty/libjpeg-turbo/src/jsimd.h @@ -4,6 +4,7 @@ * Copyright 2009 Pierre Ossman for Cendio AB * Copyright (C) 2011, 2014, D. R. Commander. * Copyright (C) 2015-2016, 2018, Matthieu Darbois. + * Copyright (C) 2020, Arm Limited. * * Based on the x86 SIMD extension for IJG JPEG library, * Copyright (C) 1999-2006, MIYASAKA Masaru. @@ -75,6 +76,7 @@ EXTERN(void) jsimd_int_upsample(j_decompress_ptr cinfo, EXTERN(int) jsimd_can_h2v2_fancy_upsample(void); EXTERN(int) jsimd_can_h2v1_fancy_upsample(void); +EXTERN(int) jsimd_can_h1v2_fancy_upsample(void); EXTERN(void) jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, @@ -84,6 +86,10 @@ EXTERN(void) jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr); +EXTERN(void) jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, + jpeg_component_info *compptr, + JSAMPARRAY input_data, + JSAMPARRAY *output_data_ptr); EXTERN(int) jsimd_can_h2v2_merged_upsample(void); EXTERN(int) jsimd_can_h2v1_merged_upsample(void); diff --git a/3rdparty/libjpeg-turbo/src/jsimd_none.c b/3rdparty/libjpeg-turbo/src/jsimd_none.c index 3cb6c80f8aab..5b38a9fb5c99 100644 --- a/3rdparty/libjpeg-turbo/src/jsimd_none.c +++ b/3rdparty/libjpeg-turbo/src/jsimd_none.c @@ -4,6 +4,7 @@ * Copyright 2009 Pierre Ossman for Cendio AB * Copyright (C) 2009-2011, 2014, D. R. Commander. * Copyright (C) 2015-2016, 2018, Matthieu Darbois. + * Copyright (C) 2020, Arm Limited. * * Based on the x86 SIMD extension for IJG JPEG library, * Copyright (C) 1999-2006, MIYASAKA Masaru. @@ -169,6 +170,12 @@ jsimd_can_h2v1_fancy_upsample(void) return 0; } +GLOBAL(int) +jsimd_can_h1v2_fancy_upsample(void) +{ + return 0; +} + GLOBAL(void) jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) @@ -181,6 +188,12 @@ jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, { } +GLOBAL(void) +jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, + JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) +{ +} + GLOBAL(int) jsimd_can_h2v2_merged_upsample(void) { diff --git a/3rdparty/libjpeg-turbo/src/jversion.h b/3rdparty/libjpeg-turbo/src/jversion.h index 4462b941048d..2ab534af4147 100644 --- a/3rdparty/libjpeg-turbo/src/jversion.h +++ b/3rdparty/libjpeg-turbo/src/jversion.h @@ -2,9 +2,9 @@ * jversion.h * * This file was part of the Independent JPEG Group's software: - * Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding. + * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2012-2020, D. R. Commander. + * Copyright (C) 2010, 2012-2021, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -37,9 +37,9 @@ */ #define JCOPYRIGHT \ - "Copyright (C) 2009-2020 D. R. Commander\n" \ + "Copyright (C) 2009-2021 D. R. Commander\n" \ "Copyright (C) 2015, 2020 Google, Inc.\n" \ - "Copyright (C) 2019 Arm Limited\n" \ + "Copyright (C) 2019-2020 Arm Limited\n" \ "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ "Copyright (C) 2011-2016 Siarhei Siamashka\n" \ "Copyright (C) 2015 Intel Corporation\n" \ @@ -48,7 +48,7 @@ "Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \ "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \ "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ - "Copyright (C) 1991-2017 Thomas G. Lane, Guido Vollbeding" + "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" #define JCOPYRIGHT_SHORT \ - "Copyright (C) 1991-2020 The libjpeg-turbo Project and many others" + "Copyright (C) 1991-2021 The libjpeg-turbo Project and many others" diff --git a/3rdparty/libwebp/CMakeLists.txt b/3rdparty/libwebp/CMakeLists.txt index 80ab0b86ab76..9160e2024ca0 100644 --- a/3rdparty/libwebp/CMakeLists.txt +++ b/3rdparty/libwebp/CMakeLists.txt @@ -32,7 +32,9 @@ endif() # Define the library target: # ---------------------------------------------------------------------------------- -add_definitions(-DWEBP_USE_THREAD) +if(NOT OPENCV_DISABLE_THREAD_SUPPORT) + add_definitions(-DWEBP_USE_THREAD) +endif() add_library(${WEBP_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs} ${lib_hdrs}) if(ANDROID) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bd4bf5f0dcc..dd862bb1549e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -467,6 +467,7 @@ OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF I OCV_OPTION(BUILD_CUDA_STUBS "Build CUDA modules stubs when no CUDA SDK" OFF IF (NOT APPLE_FRAMEWORK) ) OCV_OPTION(BUILD_JAVA "Enable Java support" (ANDROID OR NOT CMAKE_CROSSCOMPILING) IF (ANDROID OR (NOT APPLE_FRAMEWORK AND NOT WINRT)) ) OCV_OPTION(BUILD_OBJC "Enable Objective-C support" ON IF APPLE_FRAMEWORK ) +OCV_OPTION(BUILD_KOTLIN_EXTENSIONS "Build Kotlin extensions (Android)" ON IF ANDROID ) # OpenCV installation options # =================================================== @@ -510,10 +511,11 @@ OCV_OPTION(CV_TRACE "Enable OpenCV code trace" ON) OCV_OPTION(OPENCV_GENERATE_SETUPVARS "Generate setup_vars* scripts" ON IF (NOT ANDROID AND NOT APPLE_FRAMEWORK) ) OCV_OPTION(ENABLE_CONFIG_VERIFICATION "Fail build if actual configuration doesn't match requested (WITH_XXX != HAVE_XXX)" OFF) OCV_OPTION(OPENCV_ENABLE_MEMALIGN "Enable posix_memalign or memalign usage" ON) +OCV_OPTION(OPENCV_DISABLE_FILESYSTEM_SUPPORT "Disable filesystem support" OFF) +OCV_OPTION(OPENCV_DISABLE_THREAD_SUPPORT "Build the library without multi-threaded code." OFF) OCV_OPTION(ENABLE_PYLINT "Add target with Pylint checks" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) ) OCV_OPTION(ENABLE_FLAKE8 "Add target with Python flake8 checker" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) ) -OCV_OPTION(OPENCV_DISABLE_FILESYSTEM_SUPPORT "Disable filesystem support" OFF) if(ENABLE_IMPL_COLLECTION) add_definitions(-DCV_COLLECT_IMPL_DATA) @@ -665,6 +667,11 @@ if(UNIX) set(HAVE_PTHREAD 1) endif() + # Ensure that libpthread is not listed as one of the libraries to pass to the linker. + if (OPENCV_DISABLE_THREAD_SUPPORT) + list(REMOVE_ITEM OPENCV_LINKER_LIBS pthread) + endif() + if(OPENCV_ENABLE_MEMALIGN) CHECK_SYMBOL_EXISTS(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H) @@ -1458,6 +1465,15 @@ ocv_build_features_string(parallel_status EXCLUSIVE ELSE "none") status("") status(" Parallel framework:" "${parallel_status}") +if (OPENCV_DISABLE_THREAD_SUPPORT) + status("" "Multi thread code explicitly disabled with OPENCV_DISABLE_THREAD_SUPPORT.") + if(HAVE_PTHREADS_PF OR HAVE_HPX OR HAVE_OPENMP OR HAVE_GCD OR HAVE_CONCURRENCY) + message(FATAL_ERROR "Not all parallel frameworks have been disabled (using ${parallel_status}).") + endif() + if(HAVE_PTHREAD) + message(FATAL_ERROR "Thread execution might be in use in some component.") + endif() +endif() if(CV_TRACE OR OPENCV_TRACE) ocv_build_features_string(trace_status EXCLUSIVE diff --git a/apps/model-diagnostics/model_diagnostics.cpp b/apps/model-diagnostics/model_diagnostics.cpp index 2ffeaa1ea5b9..d3934577aec6 100644 --- a/apps/model-diagnostics/model_diagnostics.cpp +++ b/apps/model-diagnostics/model_diagnostics.cpp @@ -1,6 +1,6 @@ /************************************************* USAGE: -./model_diagnostics -m +./model_diagnostics -m **************************************************/ #include #include @@ -32,7 +32,7 @@ static std::string checkFileExists(const std::string& fileName) } std::string diagnosticKeys = - "{ model m | | Path to the model .onnx file. }" + "{ model m | | Path to the model file. }" "{ config c | | Path to the model configuration file. }" "{ framework f | | [Optional] Name of the model framework. }"; @@ -41,7 +41,7 @@ std::string diagnosticKeys = int main( int argc, const char** argv ) { CommandLineParser argParser(argc, argv, diagnosticKeys); - argParser.about("Use this tool to run the diagnostics of provided ONNX model" + argParser.about("Use this tool to run the diagnostics of provided ONNX/TF model" "to obtain the information about its support (supported layers)."); if (argc == 1) diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake index a161b6eb8b64..2917dd33d5ee 100644 --- a/cmake/OpenCVCompilerOptions.cmake +++ b/cmake/OpenCVCompilerOptions.cmake @@ -178,8 +178,17 @@ if(CV_GCC OR CV_CLANG) add_extra_compiler_option(-Wno-long-long) endif() - # We need pthread's - if(UNIX AND NOT ANDROID AND NOT (APPLE AND CV_CLANG)) # TODO + # We need pthread's, unless we have explicitly disabled multi-thread execution. + if(NOT OPENCV_DISABLE_THREAD_SUPPORT + AND ( + (UNIX + AND NOT ANDROID + AND NOT (APPLE AND CV_CLANG) + AND NOT EMSCRIPTEN + ) + OR (EMSCRIPTEN AND WITH_PTHREADS_PF) # https://github.com/opencv/opencv/issues/20285 + ) + ) # TODO add_extra_compiler_option(-pthread) endif() diff --git a/cmake/OpenCVDetectHalide.cmake b/cmake/OpenCVDetectHalide.cmake index 790f69205662..4828c299aead 100644 --- a/cmake/OpenCVDetectHalide.cmake +++ b/cmake/OpenCVDetectHalide.cmake @@ -9,9 +9,14 @@ set(HALIDE_ROOT_DIR "${HALIDE_ROOT_DIR}" CACHE PATH "Halide root directory") if(NOT HAVE_HALIDE) find_package(Halide QUIET) # Try CMake-based config files if(Halide_FOUND) - set(HALIDE_INCLUDE_DIRS "${Halide_INCLUDE_DIRS}" CACHE PATH "Halide include directories" FORCE) - set(HALIDE_LIBRARIES "${Halide_LIBRARIES}" CACHE PATH "Halide libraries" FORCE) - set(HAVE_HALIDE TRUE) + if(TARGET Halide::Halide) # modern Halide scripts defines imported target + set(HALIDE_INCLUDE_DIRS "") + set(HALIDE_LIBRARIES "Halide::Halide") + set(HAVE_HALIDE TRUE) + else() + # using HALIDE_INCLUDE_DIRS / Halide_LIBRARIES + set(HAVE_HALIDE TRUE) + endif() endif() endif() @@ -28,18 +33,15 @@ if(NOT HAVE_HALIDE AND HALIDE_ROOT_DIR) ) if(HALIDE_LIBRARY AND HALIDE_INCLUDE_DIR) # TODO try_compile - set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}" CACHE PATH "Halide include directories" FORCE) - set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}" CACHE PATH "Halide libraries" FORCE) + set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}") + set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}") set(HAVE_HALIDE TRUE) endif() - if(NOT HAVE_HALIDE) - ocv_clear_vars(HALIDE_LIBRARIES HALIDE_INCLUDE_DIRS CACHE) - endif() endif() if(HAVE_HALIDE) - include_directories(${HALIDE_INCLUDE_DIRS}) + if(HALIDE_INCLUDE_DIRS) + include_directories(${HALIDE_INCLUDE_DIRS}) + endif() list(APPEND OPENCV_LINKER_LIBS ${HALIDE_LIBRARIES}) -else() - ocv_clear_vars(HALIDE_INCLUDE_DIRS HALIDE_LIBRARIES) endif() diff --git a/cmake/OpenCVDetectInferenceEngine.cmake b/cmake/OpenCVDetectInferenceEngine.cmake index 216c02c3ccc2..b9fd07bbfbb1 100644 --- a/cmake/OpenCVDetectInferenceEngine.cmake +++ b/cmake/OpenCVDetectInferenceEngine.cmake @@ -134,12 +134,21 @@ endif() # Add more features to the target if(INF_ENGINE_TARGET) - if(NOT INF_ENGINE_RELEASE) - message(WARNING "InferenceEngine version has not been set, 2021.3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.") + if(DEFINED InferenceEngine_VERSION) + message(STATUS "InferenceEngine: ${InferenceEngine_VERSION}") + if(NOT INF_ENGINE_RELEASE AND NOT (InferenceEngine_VERSION VERSION_LESS "2021.4")) + math(EXPR INF_ENGINE_RELEASE_INIT "${InferenceEngine_VERSION_MAJOR} * 1000000 + ${InferenceEngine_VERSION_MINOR} * 10000 + ${InferenceEngine_VERSION_PATCH} * 100") + endif() + endif() + if(NOT INF_ENGINE_RELEASE AND NOT INF_ENGINE_RELEASE_INIT) + message(WARNING "InferenceEngine version has not been set, 2021.4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.") + set(INF_ENGINE_RELEASE_INIT "2021040000") + elseif(DEFINED INF_ENGINE_RELEASE) + set(INF_ENGINE_RELEASE_INIT "${INF_ENGINE_RELEASE}") endif() - set(INF_ENGINE_RELEASE "2021030000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)") + set(INF_ENGINE_RELEASE "${INF_ENGINE_RELEASE_INIT}" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)") set_target_properties(${INF_ENGINE_TARGET} PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}" + INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}" ) endif() diff --git a/cmake/OpenCVFindLibsGUI.cmake b/cmake/OpenCVFindLibsGUI.cmake index e3593d4dc9b3..c8ec55b58864 100644 --- a/cmake/OpenCVFindLibsGUI.cmake +++ b/cmake/OpenCVFindLibsGUI.cmake @@ -2,16 +2,7 @@ # Detect 3rd-party GUI libraries # ---------------------------------------------------------------------------- -#--- Win32 UI --- -ocv_clear_vars(HAVE_WIN32UI) -if(WITH_WIN32UI) - try_compile(HAVE_WIN32UI - "${OpenCV_BINARY_DIR}" - "${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp" - CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32") -endif() - -# --- QT4 --- +# --- QT4/5 --- ocv_clear_vars(HAVE_QT HAVE_QT5) if(WITH_QT) if(NOT WITH_QT EQUAL 4) @@ -34,41 +25,6 @@ if(WITH_QT) endif() endif() -# --- GTK --- -ocv_clear_vars(HAVE_GTK HAVE_GTK3 HAVE_GTHREAD HAVE_GTKGLEXT) -if(WITH_GTK AND NOT HAVE_QT) - if(NOT WITH_GTK_2_X) - ocv_check_modules(GTK3 gtk+-3.0) - if(HAVE_GTK3) - ocv_append_build_options(HIGHGUI GTK3) - set(HAVE_GTK TRUE) - endif() - endif() - if(NOT HAVE_GTK) - ocv_check_modules(GTK2 gtk+-2.0) - if(HAVE_GTK2) - if (GTK2_VERSION VERSION_LESS MIN_VER_GTK) - message (FATAL_ERROR "GTK support requires a minimum version of ${MIN_VER_GTK} (${GTK2_VERSION} found)") - else() - ocv_append_build_options(HIGHGUI GTK2) - set(HAVE_GTK TRUE) - endif() - endif() - endif() - ocv_check_modules(GTHREAD gthread-2.0) - if(HAVE_GTK AND NOT HAVE_GTHREAD) - message(FATAL_ERROR "gthread not found. This library is required when building with GTK support") - else() - ocv_append_build_options(HIGHGUI GTHREAD) - endif() - if(WITH_OPENGL AND NOT HAVE_GTK3) - ocv_check_modules(GTKGLEXT gtkglext-1.0) - if(HAVE_GTKGLEXT) - ocv_append_build_options(HIGHGUI GTKGLEXT) - endif() - endif() -endif() - # --- OpenGl --- ocv_clear_vars(HAVE_OPENGL HAVE_QT_OPENGL) if(WITH_OPENGL) diff --git a/cmake/OpenCVMinDepVersions.cmake b/cmake/OpenCVMinDepVersions.cmake index ce0c0ba8165c..db225e2ab5b4 100644 --- a/cmake/OpenCVMinDepVersions.cmake +++ b/cmake/OpenCVMinDepVersions.cmake @@ -6,4 +6,3 @@ set(MIN_VER_CUDNN 7.5) set(MIN_VER_PYTHON2 2.7) set(MIN_VER_PYTHON3 3.2) set(MIN_VER_ZLIB 1.2.3) -set(MIN_VER_GTK 2.18.0) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 0e783dfec68e..7c48aad9c295 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -1183,6 +1183,9 @@ function(ocv_add_perf_tests) if(TARGET opencv_videoio_plugins) add_dependencies(${the_target} opencv_videoio_plugins) endif() + if(TARGET opencv_highgui_plugins) + add_dependencies(${the_target} opencv_highgui_plugins) + endif() if(HAVE_HPX) message("Linking HPX to Perf test of module ${name}") @@ -1278,6 +1281,9 @@ function(ocv_add_accuracy_tests) if(TARGET opencv_videoio_plugins) add_dependencies(${the_target} opencv_videoio_plugins) endif() + if(TARGET opencv_highgui_plugins) + add_dependencies(${the_target} opencv_highgui_plugins) + endif() if(HAVE_HPX) message("Linking HPX to Perf test of module ${name}") @@ -1368,6 +1374,9 @@ function(ocv_add_samples) if(TARGET opencv_videoio_plugins) add_dependencies(${the_target} opencv_videoio_plugins) endif() + if(TARGET opencv_highgui_plugins) + add_dependencies(${the_target} opencv_highgui_plugins) + endif() if(INSTALL_BIN_EXAMPLES) install(TARGETS ${the_target} RUNTIME DESTINATION "${OPENCV_SAMPLES_BIN_INSTALL_PATH}/${module_id}" COMPONENT samples) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 252078bdf776..39445150a911 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -1973,3 +1973,9 @@ if(NOT BUILD_SHARED_LIBS AND (CMAKE_VERSION VERSION_LESS "3.14.0")) else() ocv_update(OPENCV_3RDPARTY_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL") endif() + + +# +# Include configuration override settings +# +include(cmake/vars/EnableModeVars.cmake) diff --git a/cmake/android/android_gradle_projects.cmake b/cmake/android/android_gradle_projects.cmake index 2e34a20d97a7..e07d26b5bbd9 100644 --- a/cmake/android/android_gradle_projects.cmake +++ b/cmake/android/android_gradle_projects.cmake @@ -2,6 +2,17 @@ set(ANDROID_GRADLE_PLUGIN_VERSION "3.2.1" CACHE STRING "Android Gradle Plugin version") message(STATUS "Android Gradle Plugin version: ${ANDROID_GRADLE_PLUGIN_VERSION}") +set(KOTLIN_PLUGIN_VERSION "1.4.10" CACHE STRING "Kotlin Plugin version") +message(STATUS "kotlin Plugin version: ${KOTLIN_GRADLE_PLUGIN_VERSION}") + +if(BUILD_KOTLIN_EXTENSIONS) + set(KOTLIN_PLUGIN_DECLARATION "apply plugin: 'kotlin-android'" CACHE STRING "Kotlin Plugin version") + set(KOTLIN_STD_LIB "implementation 'org.jetbrains.kotlin:kotlin-stdlib:${KOTLIN_PLUGIN_VERSION}'" CACHE STRING "Kotlin Standard Library dependency") +else() + set(KOTLIN_PLUGIN_DECLARATION "" CACHE STRING "Kotlin Plugin version") + set(KOTLIN_STD_LIB "" CACHE STRING "Kotlin Standard Library dependency") +endif() + set(GRADLE_VERSION "5.6.4" CACHE STRING "Gradle version") message(STATUS "Gradle version: ${GRADLE_VERSION}") diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index c0f073604bc8..6439d8b43f06 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -28,9 +28,6 @@ /* Clp support */ #cmakedefine HAVE_CLP -/* Cocoa API */ -#cmakedefine HAVE_COCOA - /* NVIDIA CUDA Runtime API*/ #cmakedefine HAVE_CUDA @@ -56,12 +53,6 @@ /* Geospatial Data Abstraction Library */ #cmakedefine HAVE_GDAL -/* GTK+ 2.0 Thread support */ -#cmakedefine HAVE_GTHREAD - -/* GTK+ 2.x toolkit */ -#cmakedefine HAVE_GTK - /* Halide support */ #cmakedefine HAVE_HALIDE @@ -121,12 +112,6 @@ /* parallel_for with pthreads */ #cmakedefine HAVE_PTHREADS_PF -/* Qt support */ -#cmakedefine HAVE_QT - -/* Qt OpenGL support */ -#cmakedefine HAVE_QT_OPENGL - /* Intel Threading Building Blocks */ #cmakedefine HAVE_TBB @@ -136,9 +121,6 @@ /* TIFF codec */ #cmakedefine HAVE_TIFF -/* Win32 UI */ -#cmakedefine HAVE_WIN32UI - /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #cmakedefine WORDS_BIGENDIAN diff --git a/cmake/vars/EnableModeVars.cmake b/cmake/vars/EnableModeVars.cmake new file mode 100644 index 000000000000..b3c4e79c46d1 --- /dev/null +++ b/cmake/vars/EnableModeVars.cmake @@ -0,0 +1,18 @@ +set(__OCV_MODE_VARS_DIR "${CMAKE_CURRENT_LIST_DIR}") + +macro(ocv_change_mode_var) + set(__var "${ARGV0}") + set(__mode "${ARGV1}") + set(__value "${ARGV2}") + if(__mode STREQUAL "MODIFIED_ACCESS" AND __value) + if(NOT __applied_mode_${__var}) + include("${__OCV_MODE_VARS_DIR}/${__var}.cmake") + set(__applied_mode_${__var} 1) + else() + #message("Mode is already applied: ${__var}") + endif() + endif() +endmacro() + +variable_watch(OPENCV_DISABLE_THREAD_SUPPORT ocv_change_mode_var) +set(OPENCV_DISABLE_THREAD_SUPPORT "${OPENCV_DISABLE_THREAD_SUPPORT}") diff --git a/cmake/vars/OPENCV_DISABLE_THREAD_SUPPORT.cmake b/cmake/vars/OPENCV_DISABLE_THREAD_SUPPORT.cmake new file mode 100644 index 000000000000..5f5fc0204dfc --- /dev/null +++ b/cmake/vars/OPENCV_DISABLE_THREAD_SUPPORT.cmake @@ -0,0 +1,28 @@ +# Force removal of code conditionally compiled with `#if +# HAVE_PTHREAD`. +ocv_update(HAVE_PTHREAD 0) + +# There components are disabled because they require +# multi-threaded execution. +ocv_update(WITH_PROTOBUF OFF) +ocv_update(WITH_GSTREAMER OFF) +ocv_update(WITH_IPP OFF) +ocv_update(WITH_ITT OFF) +ocv_update(WITH_OPENCL OFF) +ocv_update(WITH_VA OFF) +ocv_update(WITH_VA_INTEL OFF) + +# Disable bindings +ocv_update(BUILD_opencv_python2 OFF) +ocv_update(BUILD_opencv_python3 OFF) +ocv_update(BUILD_JAVA OFF) +ocv_update(BUILD_opencv_java OFF) + +# These modules require `#include +# <[thread|mutex|condition_variable|future]>` and linkage into +# `libpthread` to work. +ocv_update(BUILD_opencv_objdetect OFF) +ocv_update(BUILD_opencv_gapi OFF) +ocv_update(BUILD_opencv_dnn OFF) + +set(OPJ_USE_THREAD "OFF" CACHE INTERNAL "") diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 26ad42b1e5fb..ce207d3e318f 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -106,7 +106,7 @@ RECURSIVE = YES EXCLUDE = @CMAKE_DOXYGEN_EXCLUDE_LIST@ EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = *.inl.hpp *.impl.hpp *_detail.hpp */cudev/**/detail/*.hpp *.m */opencl/runtime/* */legacy/* *_c.h @DOXYGEN_EXCLUDE_PATTERNS@ -EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__* T __CV* +EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__* T __CV* cv::gapi::detail* EXAMPLE_PATH = @CMAKE_DOXYGEN_EXAMPLE_PATH@ EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = YES diff --git a/doc/opencv.bib b/doc/opencv.bib index d44b0f5293e7..d0661e8d5f0b 100644 --- a/doc/opencv.bib +++ b/doc/opencv.bib @@ -850,12 +850,12 @@ @article{Park94 journal = {IEEE Transactions on Robotics and Automation}, title = {Robot sensor calibration: solving AX=XB on the Euclidean group}, year = {1994}, + month = oct, volume = {10}, number = {5}, pages = {717-721}, doi = {10.1109/70.326576}, - ISSN = {1042-296X}, - month = {Oct} + issn = {1042-296X} } @inproceedings{PM03, author = {P{\'e}rez, Patrick and Gangnet, Michel and Blake, Andrew}, @@ -1051,12 +1051,12 @@ @article{Tsai89 journal = {IEEE Transactions on Robotics and Automation}, title = {A new technique for fully autonomous and efficient 3D robotics hand/eye calibration}, year = {1989}, + month = jun, volume = {5}, number = {3}, pages = {345-358}, doi = {10.1109/70.34770}, - ISSN = {1042-296X}, - month = {June} + issn = {1042-296X} } @inproceedings{UES01, author = {Uyttendaele, Matthew and Eden, Ashley and Skeliski, R}, @@ -1324,3 +1324,13 @@ @inproceedings{zhou2017east pages={5551--5560}, year={2017} } +@article{umeyama1991least, + title={Least-squares estimation of transformation parameters between two point patterns}, + author={Umeyama, Shinji}, + journal={IEEE Computer Architecture Letters}, + volume={13}, + number={04}, + pages={376--380}, + year={1991}, + publisher={IEEE Computer Society} +} diff --git a/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.markdown b/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.markdown index e24e692087c5..60e5686934d7 100644 --- a/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.markdown +++ b/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.markdown @@ -40,12 +40,12 @@ using **cv.Sobel()**). Then comes the main part. After this, they created a score, basically an equation, which determines if a window can contain a corner or not. -\f[R = det(M) - k(trace(M))^2\f] +\f[R = \det(M) - k(\operatorname{trace}(M))^2\f] where - - \f$det(M) = \lambda_1 \lambda_2\f$ - - \f$trace(M) = \lambda_1 + \lambda_2\f$ - - \f$\lambda_1\f$ and \f$\lambda_2\f$ are the eigenvalues of M + - \f$\det(M) = \lambda_1 \lambda_2\f$ + - \f$\operatorname{trace}(M) = \lambda_1 + \lambda_2\f$ + - \f$\lambda_1\f$ and \f$\lambda_2\f$ are the eigenvalues of \f$M\f$ So the magnitudes of these eigenvalues decide whether a region is a corner, an edge, or flat. diff --git a/doc/py_tutorials/py_feature2d/py_shi_tomasi/py_shi_tomasi.markdown b/doc/py_tutorials/py_feature2d/py_shi_tomasi/py_shi_tomasi.markdown index 1229581ce685..c5d29493e403 100644 --- a/doc/py_tutorials/py_feature2d/py_shi_tomasi/py_shi_tomasi.markdown +++ b/doc/py_tutorials/py_feature2d/py_shi_tomasi/py_shi_tomasi.markdown @@ -20,7 +20,7 @@ Harris Corner Detector. The scoring function in Harris Corner Detector was given Instead of this, Shi-Tomasi proposed: -\f[R = min(\lambda_1, \lambda_2)\f] +\f[R = \min(\lambda_1, \lambda_2)\f] If it is a greater than a threshold value, it is considered as a corner. If we plot it in \f$\lambda_1 - \lambda_2\f$ space as we did in Harris Corner Detector, we get an image as below: @@ -28,7 +28,7 @@ If it is a greater than a threshold value, it is considered as a corner. If we p ![image](images/shitomasi_space.png) From the figure, you can see that only when \f$\lambda_1\f$ and \f$\lambda_2\f$ are above a minimum value, -\f$\lambda_{min}\f$, it is considered as a corner(green region). +\f$\lambda_{\min}\f$, it is considered as a corner(green region). Code ---- diff --git a/doc/py_tutorials/py_feature2d/py_sift_intro/py_sift_intro.markdown b/doc/py_tutorials/py_feature2d/py_sift_intro/py_sift_intro.markdown index dee4df774ae8..bbbae6a3e6c8 100644 --- a/doc/py_tutorials/py_feature2d/py_sift_intro/py_sift_intro.markdown +++ b/doc/py_tutorials/py_feature2d/py_sift_intro/py_sift_intro.markdown @@ -156,7 +156,7 @@ sift = cv.SIFT_create() kp, des = sift.detectAndCompute(gray,None) @endcode Here kp will be a list of keypoints and des is a numpy array of shape -\f$Number\_of\_Keypoints \times 128\f$. +\f$\text{(Number of Keypoints)} \times 128\f$. So we got keypoints, descriptors etc. Now we want to see how to match keypoints in different images. That we will learn in coming chapters. diff --git a/doc/tutorials/introduction/config_reference/config_reference.markdown b/doc/tutorials/introduction/config_reference/config_reference.markdown index cea8d0c39f11..58b4ed55ca41 100644 --- a/doc/tutorials/introduction/config_reference/config_reference.markdown +++ b/doc/tutorials/introduction/config_reference/config_reference.markdown @@ -396,13 +396,14 @@ There are multiple less popular frameworks which can be used to read and write v ### videoio plugins -Some _videoio_ backends can be built as plugins thus breaking strict dependency on third-party libraries and making them optional at runtime. Following options can be used to control this mechanism: +Since version 4.1.0 some _videoio_ backends can be built as plugins thus breaking strict dependency on third-party libraries and making them optional at runtime. Following options can be used to control this mechanism: | Option | Default | Description | | --------| ------ | ------- | | `VIDEOIO_ENABLE_PLUGINS` | _ON_ | Enable or disable plugins completely. | | `VIDEOIO_PLUGIN_LIST` | _empty_ | Comma- or semicolon-separated list of backend names to be compiled as plugins. Supported names are _ffmpeg_, _gstreamer_, _msmf_, _mfx_ and _all_. | -| `VIDEOIO_ENABLE_STRICT_PLUGIN_CHECK` | _ON_ | Enable strict runtime version check to only allow plugins built with the same version of OpenCV. | + +Check @ref tutorial_general_install for standalone plugins build instructions. ## Parallel processing {#tutorial_config_reference_func_core} @@ -421,6 +422,17 @@ Some of OpenCV algorithms can use multithreading to accelerate processing. OpenC @note OpenCV can download and build TBB library from GitHub, this functionality can be enabled with the `BUILD_TBB` option. +### Threading plugins + +Since version 4.5.2 OpenCV supports dynamically loaded threading backends. At this moment only separate compilation process is supported: first you have to build OpenCV with some _default_ parallel backend (e.g. pthreads), then build each plugin and copy resulting binaries to the _lib_ or _bin_ folder. + +| Option | Default | Description | +| ------ | ------- | ----------- | +| PARALLEL_ENABLE_PLUGINS | ON | Enable plugin support, if this option is disabled OpenCV will not try to load anything | + +Check @ref tutorial_general_install for standalone plugins build instructions. + + ## GUI backends (highgui module) {#tutorial_config_reference_highgui} OpenCV relies on various GUI libraries for window drawing. @@ -442,6 +454,18 @@ OpenCV relies on various GUI libraries for window drawing. OpenGL integration can be used to draw HW-accelerated windows with following backends: GTK, WIN32 and Qt. And enables basic interoperability with OpenGL, see @ref core_opengl and @ref highgui_opengl for details. +### highgui plugins + +Since OpenCV 4.5.3 GTK backend can be build as a dynamically loaded plugin. Following options can be used to control this mechanism: + +| Option | Default | Description | +| --------| ------ | ------- | +| `HIGHGUI_ENABLE_PLUGINS` | _ON_ | Enable or disable plugins completely. | +| `HIGHGUI_PLUGIN_LIST` | _empty_ | Comma- or semicolon-separated list of backend names to be compiled as plugins. Supported names are _gtk_, _gtk2_, _gtk3_, and _all_. | + +Check @ref tutorial_general_install for standalone plugins build instructions. + + ## Deep learning neural networks inference backends and options (dnn module) {#tutorial_config_reference_dnn} OpenCV have own DNN inference module which have own build-in engine, but can also use other libraries for optimized processing. Multiple backends can be enabled in single build. Selection happens at runtime automatically or manually. diff --git a/doc/tutorials/introduction/cross_referencing/tutorial_cross_referencing.markdown b/doc/tutorials/introduction/cross_referencing/tutorial_cross_referencing.markdown index 4908771aec0d..749356063547 100644 --- a/doc/tutorials/introduction/cross_referencing/tutorial_cross_referencing.markdown +++ b/doc/tutorials/introduction/cross_referencing/tutorial_cross_referencing.markdown @@ -46,14 +46,14 @@ Open your Doxyfile using your favorite text editor and search for the key `TAGFILES`. Change it as follows: @code -TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.5.2 +TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.5.3 @endcode If you had other definitions already, you can append the line using a `\`: @code TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \ - ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.5.2 + ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.5.3 @endcode Doxygen can now use the information from the tag file to link to the OpenCV diff --git a/doc/tutorials/introduction/general_install/general_install.markdown b/doc/tutorials/introduction/general_install/general_install.markdown index e8c93f430eea..7b0c5d2b068a 100644 --- a/doc/tutorials/introduction/general_install/general_install.markdown +++ b/doc/tutorials/introduction/general_install/general_install.markdown @@ -105,7 +105,7 @@ cmake --build make ``` -## Step 3: Install {#tutorial_general_install_sources_4} +## (optional) Step 3: Install {#tutorial_general_install_sources_4} During installation procedure build results and other files from build directory will be copied to the install location. Default installation location is `/usr/local` on UNIX and `C:/Program Files` on Windows. This location can be changed at the configuration step by setting `CMAKE_INSTALL_PREFIX` option. To perform installation run the following command: ``` @@ -117,3 +117,32 @@ This step is optional, OpenCV can be used directly from the build directory. @note If the installation root location is a protected system directory, so the installation process must be run with superuser or administrator privileges (e.g. `sudo cmake ...`). + + +## (optional) Step 4: Build plugins {#tutorial_general_install_plugins_4} + +It is possible to decouple some of OpenCV dependencies and make them optional by extracting parts of the code into dynamically-loaded plugins. It helps to produce adaptive binary distributions which can work on systems with less dependencies and extend functionality just by installing missing libraries. For now modules _core_, _videoio_ and _highgui_ support this mechanism for some of their dependencies. In some cases it is possible to build plugins together with OpenCV by setting options like `VIDEOIO_PLUGIN_LIST` or `HIGHGUI_PLUGIN_LIST`, more options related to this scenario can be found in the @ref tutorial_config_reference. In other cases plugins should be built separately in their own build procedure and this section describes such standalone build process. + +@note It is recommended to use compiler, configuration and build options which are compatible to the one used for OpenCV build, otherwise resulting library can refuse to load or cause other runtime problems. Note that some functionality can be limited or work slower when backends are loaded dynamically due to extra barrier between OpenCV and corresponding third-party library. + +Build procedure is similar to the main OpenCV build, but you have to use special CMake projects located in corresponding subdirectories, these folders can also contain reference scripts and Docker images. It is important to use `opencv__` name prefix for plugins so that loader is able to find them. Each supported prefix can be used to load only one library, however multiple candidates can be probed for a single prefix. For example, you can have _libopencv_videoio_ffmpeg_3.so_ and _libopencv_videoio_ffmpeg_4.so_ plugins and the first one which can be loaded successfully will occupy internal slot and stop probing process. Possible prefixes and project locations are presented in the table below: + +| module | backends | location | +| ------ | -------- | -------- | +| core | parallel_tbb, parallel_onetbb, parallel_openmp | _opencv/modules/core/misc/plugins_ | +| highgui | gtk, gtk2, gtk3 | _opencv/modules/highgui/misc/plugins_ | +| videoio | ffmpeg, gstreamer, intel_mfx, msmf | _opencv/modules/videoio/misc_ | + +Example: +```.sh +# set-up environment for TBB detection, for example: +# export TBB_DIR= +cmake -G \ + -DOPENCV_PLUGIN_NAME=opencv_core_tbb_ \ + -DOPENCV_PLUGIN_DESTINATION= \ + -DCMAKE_BUILD_TYPE= \ + /modules/core/misc/plugins/parallel_tbb +cmake --build . --config +``` + +@note On Windows plugins must be linked with existing OpenCV build. Set `OpenCV_DIR` environment or CMake variable to the directory with _OpenCVConfig.cmake_ file, it can be OpenCV build directory or some path in the location where you performed installation. diff --git a/modules/calib3d/include/opencv2/calib3d.hpp b/modules/calib3d/include/opencv2/calib3d.hpp index ce79a33405a4..4928df65d1f1 100644 --- a/modules/calib3d/include/opencv2/calib3d.hpp +++ b/modules/calib3d/include/opencv2/calib3d.hpp @@ -748,7 +748,7 @@ CV_EXPORTS_W Mat findHomography(InputArray srcPoints, InputArray dstPoints, Outp @param Qz Optional output 3x3 rotation matrix around z-axis. The function computes a RQ decomposition using the given rotations. This function is used in -decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix into a camera +#decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix into a camera and a rotation matrix. It optionally returns three rotation matrices, one for each axis, and the three Euler angles in @@ -802,7 +802,7 @@ CV_EXPORTS_W void decomposeProjectionMatrix( InputArray projMatrix, OutputArray The function computes partial derivatives of the elements of the matrix product \f$A*B\f$ with regard to the elements of each of the two input matrices. The function is used to compute the Jacobian -matrices in stereoCalibrate but can also be used in any other similar optimization function. +matrices in #stereoCalibrate but can also be used in any other similar optimization function. */ CV_EXPORTS_W void matMulDeriv( InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB ); @@ -831,7 +831,7 @@ where \f$\mathrm{rodrigues}\f$ denotes a rotation vector to a rotation matrix tr \f$\mathrm{rodrigues}^{-1}\f$ denotes the inverse transformation. See Rodrigues for details. Also, the functions can compute the derivatives of the output vectors with regards to the input -vectors (see matMulDeriv ). The functions are used inside stereoCalibrate but can also be used in +vectors (see matMulDeriv ). The functions are used inside #stereoCalibrate but can also be used in your own code where Levenberg-Marquardt or another gradient-based solver is used to optimize a function that contains a matrix multiplication. */ @@ -1052,7 +1052,7 @@ a 3D point expressed in the world frame into the camera frame: arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of modules/calib3d/src/solvepnp.cpp version 2.4.9) - The P3P algorithm requires image points to be in an array of shape (N,1,2) due - to its calling of cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) + to its calling of #undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) which requires 2-channel information. - Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints = @@ -1257,7 +1257,7 @@ vectors, respectively, and further optimizes them. - @ref SOLVEPNP_ITERATIVE Iterative method is based on a Levenberg-Marquardt optimization. In this case the function finds such a pose that minimizes reprojection error, that is the sum of squared distances between the observed projections imagePoints and the projected (using -projectPoints ) objectPoints . + #projectPoints ) objectPoints . - @ref SOLVEPNP_P3P Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang "Complete Solution Classification for the Perspective-Three-Point Problem" (@cite gao2003complete). In this case the function requires exactly four object and image points. @@ -1393,7 +1393,7 @@ a 3D point expressed in the world frame into the camera frame: arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of modules/calib3d/src/solvepnp.cpp version 2.4.9) - The P3P algorithm requires image points to be in an array of shape (N,1,2) due - to its calling of cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) + to its calling of #undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) which requires 2-channel information. - Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints = @@ -1426,7 +1426,7 @@ CV_EXPORTS_W int solvePnPGeneric( InputArray objectPoints, InputArray imagePoint @param objectPoints Vector of vectors of the calibration pattern points in the calibration pattern coordinate space. In the old interface all the per-view vectors are concatenated. See -calibrateCamera for details. +#calibrateCamera for details. @param imagePoints Vector of vectors of the projections of the calibration pattern points. In the old interface all the per-view vectors are concatenated. @param imageSize Image size in pixels used to initialize the principal point. @@ -1520,7 +1520,7 @@ Each entry stands for one corner of the pattern and can have one of the followin - 3 = left-top corner of a black cell with a white marker dot - 4 = left-top corner of a white cell with a black marker dot (pattern origin in case of markers otherwise first corner) -The function is analog to findchessboardCorners but uses a localized radon +The function is analog to #findChessboardCorners but uses a localized radon transformation approximated by box filters being more robust to all sort of noise, faster on larger images and is able to directly return the sub-pixel position of the internal chessboard corners. The Method is based on the paper @@ -1570,7 +1570,7 @@ and should be below ~3.0 pixels. @param image Gray image used to find chessboard corners @param patternSize Size of a found chessboard pattern -@param corners Corners found by findChessboardCorners(SB) +@param corners Corners found by #findChessboardCornersSB @param rise_distance Rise distance 0.8 means 10% ... 90% of the final signal strength @param vertical By default edge responses for horizontal lines are calculated @param sharpness Optional output array with a sharpness value for calculated edge responses (see description) @@ -1598,9 +1598,9 @@ CV_EXPORTS_W bool find4QuadCornerSubpix( InputArray img, InputOutputArray corner @param image Destination image. It must be an 8-bit color image. @param patternSize Number of inner corners per a chessboard row and column (patternSize = cv::Size(points_per_row,points_per_column)). -@param corners Array of detected corners, the output of findChessboardCorners. +@param corners Array of detected corners, the output of #findChessboardCorners. @param patternWasFound Parameter indicating whether the complete board was found or not. The -return value of findChessboardCorners should be passed here. +return value of #findChessboardCorners should be passed here. The function draws individual chessboard corners detected either as red circles if the board was not found, or as colored corners connected with lines if the board was found. @@ -1837,21 +1837,21 @@ CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints, /** @brief Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern. -This function is an extension of calibrateCamera() with the method of releasing object which was +This function is an extension of #calibrateCamera with the method of releasing object which was proposed in @cite strobl2011iccv. In many common cases with inaccurate, unmeasured, roughly planar targets (calibration plates), this method can dramatically improve the precision of the estimated camera parameters. Both the object-releasing method and standard method are supported by this function. Use the parameter **iFixedPoint** for method selection. In the internal implementation, -calibrateCamera() is a wrapper for this function. +#calibrateCamera is a wrapper for this function. @param objectPoints Vector of vectors of calibration pattern points in the calibration pattern -coordinate space. See calibrateCamera() for details. If the method of releasing object to be used, +coordinate space. See #calibrateCamera for details. If the method of releasing object to be used, the identical calibration board must be used in each view and it must be fully visible, and all objectPoints[i] must be the same and all points should be roughly close to a plane. **The calibration target has to be rigid, or at least static if the camera (rather than the calibration target) is shifted for grabbing images.** @param imagePoints Vector of vectors of the projections of calibration pattern points. See -calibrateCamera() for details. +#calibrateCamera for details. @param imageSize Size of the image used only to initialize the intrinsic camera matrix. @param iFixedPoint The index of the 3D object point in objectPoints[0] to be fixed. It also acts as a switch for calibration method selection. If object-releasing method to be used, pass in the @@ -1861,9 +1861,9 @@ board grid is recommended to be fixed when object-releasing method being utilize \cite strobl2011iccv, two other points are also fixed. In this implementation, objectPoints[0].front and objectPoints[0].back.z are used. With object-releasing method, accurate rvecs, tvecs and newObjPoints are only possible if coordinates of these three fixed points are accurate enough. -@param cameraMatrix Output 3x3 floating-point camera matrix. See calibrateCamera() for details. -@param distCoeffs Output vector of distortion coefficients. See calibrateCamera() for details. -@param rvecs Output vector of rotation vectors estimated for each pattern view. See calibrateCamera() +@param cameraMatrix Output 3x3 floating-point camera matrix. See #calibrateCamera for details. +@param distCoeffs Output vector of distortion coefficients. See #calibrateCamera for details. +@param rvecs Output vector of rotation vectors estimated for each pattern view. See #calibrateCamera for details. @param tvecs Output vector of translation vectors estimated for each pattern view. @param newObjPoints The updated output vector of calibration pattern points. The coordinates might @@ -1871,15 +1871,15 @@ be scaled based on three fixed points. The returned coordinates are accurate onl mentioned three fixed points are accurate. If not needed, noArray() can be passed in. This parameter is ignored with standard calibration method. @param stdDeviationsIntrinsics Output vector of standard deviations estimated for intrinsic parameters. -See calibrateCamera() for details. +See #calibrateCamera for details. @param stdDeviationsExtrinsics Output vector of standard deviations estimated for extrinsic parameters. -See calibrateCamera() for details. +See #calibrateCamera for details. @param stdDeviationsObjPoints Output vector of standard deviations estimated for refined coordinates of calibration pattern points. It has the same size and order as objectPoints[0] vector. This parameter is ignored with standard calibration method. @param perViewErrors Output vector of the RMS re-projection error estimated for each pattern view. @param flags Different flags that may be zero or a combination of some predefined values. See -calibrateCamera() for details. If the method of releasing object is used, the calibration time may +#calibrateCamera for details. If the method of releasing object is used, the calibration time may be much longer. CALIB_USE_QR or CALIB_USE_LU could be used for faster calibration with potentially less precise and less stable in some rare cases. @param criteria Termination criteria for the iterative optimization algorithm. @@ -1888,7 +1888,7 @@ less precise and less stable in some rare cases. The function estimates the intrinsic camera parameters and extrinsic parameters for each of the views. The algorithm is based on @cite Zhang2000, @cite BouguetMCT and @cite strobl2011iccv. See -calibrateCamera() for other detailed explanations. +#calibrateCamera for other detailed explanations. @sa calibrateCamera, findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort */ @@ -1915,8 +1915,8 @@ CV_EXPORTS_W double calibrateCameraRO( InputArrayOfArrays objectPoints, /** @brief Computes useful camera characteristics from the camera intrinsic matrix. -@param cameraMatrix Input camera intrinsic matrix that can be estimated by calibrateCamera or -stereoCalibrate . +@param cameraMatrix Input camera intrinsic matrix that can be estimated by #calibrateCamera or +#stereoCalibrate . @param imageSize Input image size in pixels. @param apertureWidth Physical width in mm of the sensor. @param apertureHeight Physical height in mm of the sensor. @@ -2051,13 +2051,13 @@ Besides the stereo-related information, the function can also perform a full cal the two cameras. However, due to the high dimensionality of the parameter space and noise in the input data, the function can diverge from the correct solution. If the intrinsic parameters can be estimated with high accuracy for each of the cameras individually (for example, using -calibrateCamera ), you are recommended to do so and then pass @ref CALIB_FIX_INTRINSIC flag to the +#calibrateCamera ), you are recommended to do so and then pass @ref CALIB_FIX_INTRINSIC flag to the function along with the computed intrinsic parameters. Otherwise, if all the parameters are estimated at once, it makes sense to restrict some parameters, for example, pass @ref CALIB_SAME_FOCAL_LENGTH and @ref CALIB_ZERO_TANGENT_DIST flags, which is usually a reasonable assumption. -Similarly to calibrateCamera, the function minimizes the total re-projection error for all the +Similarly to #calibrateCamera, the function minimizes the total re-projection error for all the points in all the available views from both cameras. The function returns the final value of the re-projection error. */ @@ -2117,7 +2117,7 @@ pixels from the original images from the cameras are retained in the rectified i image pixels are lost). Any intermediate value yields an intermediate result between those two extreme cases. @param newImageSize New image resolution after rectification. The same size should be passed to -initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0) +#initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0) is passed (default), it is set to the original imageSize . Setting it to a larger value can help you preserve details in the original image, especially when there is a big radial distortion. @param validPixROI1 Optional output rectangles inside the rectified images where all the pixels @@ -2129,7 +2129,7 @@ are valid. If alpha=0 , the ROIs cover the whole images. Otherwise, they are lik The function computes the rotation matrices for each camera that (virtually) make both camera image planes the same plane. Consequently, this makes all the epipolar lines parallel and thus simplifies -the dense stereo correspondence problem. The function takes the matrices computed by stereoCalibrate +the dense stereo correspondence problem. The function takes the matrices computed by #stereoCalibrate as input. As output, it provides two rotation matrices and also two projection matrices in the new coordinates. The function distinguishes the following two cases: @@ -2173,7 +2173,7 @@ coordinates. The function distinguishes the following two cases: @ref CALIB_ZERO_DISPARITY is set. As you can see, the first three columns of P1 and P2 will effectively be the new "rectified" camera -matrices. The matrices, together with R1 and R2 , can then be passed to initUndistortRectifyMap to +matrices. The matrices, together with R1 and R2 , can then be passed to #initUndistortRectifyMap to initialize the rectification map for each camera. See below the screenshot from the stereo_calib.cpp sample. Some red horizontal lines pass through @@ -2196,9 +2196,9 @@ CV_EXPORTS_W void stereoRectify( InputArray cameraMatrix1, InputArray distCoeffs @param points1 Array of feature points in the first image. @param points2 The corresponding points in the second image. The same formats as in -findFundamentalMat are supported. +#findFundamentalMat are supported. @param F Input fundamental matrix. It can be computed from the same set of point pairs using -findFundamentalMat . +#findFundamentalMat . @param imgSize Size of the image. @param H1 Output rectification homography matrix for the first image. @param H2 Output rectification homography matrix for the second image. @@ -2209,7 +2209,7 @@ rejected prior to computing the homographies. Otherwise, all the points are cons The function computes the rectification transformations without knowing intrinsic parameters of the cameras and their relative position in the space, which explains the suffix "uncalibrated". Another -related difference from stereoRectify is that the function outputs not the rectification +related difference from #stereoRectify is that the function outputs not the rectification transformations in the object (3D) space, but the planar perspective transformations encoded by the homography matrices H1 and H2 . The function implements the algorithm @cite Hartley99 . @@ -2218,8 +2218,8 @@ homography matrices H1 and H2 . The function implements the algorithm @cite Hart depends on the epipolar geometry. Therefore, if the camera lenses have a significant distortion, it would be better to correct it before computing the fundamental matrix and calling this function. For example, distortion coefficients can be estimated for each head of stereo camera - separately by using calibrateCamera . Then, the images can be corrected using undistort , or - just the point coordinates can be corrected with undistortPoints . + separately by using #calibrateCamera . Then, the images can be corrected using #undistort , or + just the point coordinates can be corrected with #undistortPoints . */ CV_EXPORTS_W bool stereoRectifyUncalibrated( InputArray points1, InputArray points2, InputArray F, Size imgSize, @@ -2247,10 +2247,10 @@ assumed. @param imageSize Original image size. @param alpha Free scaling parameter between 0 (when all the pixels in the undistorted image are valid) and 1 (when all the source image pixels are retained in the undistorted image). See -stereoRectify for details. +#stereoRectify for details. @param newImgSize Image size after rectification. By default, it is set to imageSize . @param validPixROI Optional output rectangle that outlines all-good-pixels region in the -undistorted image. See roi1, roi2 description in stereoRectify . +undistorted image. See roi1, roi2 description in #stereoRectify . @param centerPrincipalPoint Optional flag that indicates whether in the new camera intrinsic matrix the principal point should be at the image center or not. By default, the principal point is chosen to best fit a subset of the source image (determined by alpha) to the corrected image. @@ -2262,7 +2262,7 @@ image pixels if there is valuable information in the corners alpha=1 , or get so When alpha\>0 , the undistorted result is likely to have some black pixels corresponding to "virtual" pixels outside of the captured distorted image. The original camera intrinsic matrix, distortion coefficients, the computed new camera intrinsic matrix, and newImageSize should be passed to -initUndistortRectifyMap to produce the maps for remap . +#initUndistortRectifyMap to produce the maps for #remap . */ CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs, Size imageSize, double alpha, Size newImgSize = Size(), @@ -2591,7 +2591,7 @@ CV_EXPORTS_W void convertPointsFromHomogeneous( InputArray src, OutputArray dst @param dst Output vector of 2D, 3D, or 4D points. The function converts 2D or 3D points from/to homogeneous coordinates by calling either -convertPointsToHomogeneous or convertPointsFromHomogeneous. +#convertPointsToHomogeneous or #convertPointsFromHomogeneous. @note The function is obsolete. Use one of the previous two functions instead. */ @@ -2630,7 +2630,7 @@ matrices sequentially). The calculated fundamental matrix may be passed further to computeCorrespondEpilines that finds the epipolar lines corresponding to the specified points. It can also be passed to -stereoRectifyUncalibrated to compute the rectification transformation. : +#stereoRectifyUncalibrated to compute the rectification transformation. : @code // Example. Estimation of fundamental matrix using the RANSAC algorithm int point_count = 100; @@ -2675,7 +2675,7 @@ be floating-point (single or double precision). @param cameraMatrix Camera intrinsic matrix \f$\cameramatrix{A}\f$ . Note that this function assumes that points1 and points2 are feature points from cameras with the same camera intrinsic matrix. If this assumption does not hold for your use case, use -`undistortPoints()` with `P = cv::NoArray()` for both cameras to transform image points +#undistortPoints with `P = cv::NoArray()` for both cameras to transform image points to normalized image coordinates, which are valid for the identity camera intrinsic matrix. When passing these coordinates, pass the identity matrix for this parameter. @param method Method for computing an essential matrix. @@ -2698,7 +2698,7 @@ This function estimates essential matrix based on the five-point algorithm solve where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the second images, respectively. The result of this function may be passed further to -decomposeEssentialMat or recoverPose to recover the relative pose between cameras. +#decomposeEssentialMat or #recoverPose to recover the relative pose between cameras. */ CV_EXPORTS_W Mat findEssentialMat( @@ -2773,13 +2773,13 @@ be floating-point (single or double precision). @param cameraMatrix1 Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . Note that this function assumes that points1 and points2 are feature points from cameras with the same camera matrix. If this assumption does not hold for your use case, use -`undistortPoints()` with `P = cv::NoArray()` for both cameras to transform image points +#undistortPoints with `P = cv::NoArray()` for both cameras to transform image points to normalized image coordinates, which are valid for the identity camera matrix. When passing these coordinates, pass the identity matrix for this parameter. @param cameraMatrix2 Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . Note that this function assumes that points1 and points2 are feature points from cameras with the same camera matrix. If this assumption does not hold for your use case, use -`undistortPoints()` with `P = cv::NoArray()` for both cameras to transform image points +#undistortPoints with `P = cv::NoArray()` for both cameras to transform image points to normalized image coordinates, which are valid for the identity camera matrix. When passing these coordinates, pass the identity matrix for this parameter. @param distCoeffs1 Input vector of distortion coefficients @@ -2807,7 +2807,7 @@ This function estimates essential matrix based on the five-point algorithm solve where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the second images, respectively. The result of this function may be passed further to -decomposeEssentialMat or recoverPose to recover the relative pose between cameras. +#decomposeEssentialMat or #recoverPose to recover the relative pose between cameras. */ CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, InputArray cameraMatrix1, InputArray distCoeffs1, @@ -2869,7 +2869,7 @@ possible pose hypotheses by doing cheirality check. The cheirality check means t triangulated 3D points should have positive depth. Some details can be found in @cite Nister03. This function can be used to process the output E and mask from @ref findEssentialMat. In this -scenario, points1 and points2 are the same input for findEssentialMat.: +scenario, points1 and points2 are the same input for #findEssentialMat : @code // Example. Estimation of fundamental matrix using the RANSAC algorithm int point_count = 100; @@ -2964,14 +2964,14 @@ CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray point @param points Input points. \f$N \times 1\f$ or \f$1 \times N\f$ matrix of type CV_32FC2 or vector\ . @param whichImage Index of the image (1 or 2) that contains the points . -@param F Fundamental matrix that can be estimated using findFundamentalMat or stereoRectify . +@param F Fundamental matrix that can be estimated using #findFundamentalMat or #stereoRectify . @param lines Output vector of the epipolar lines corresponding to the points in the other image. Each line \f$ax + by + c=0\f$ is encoded by 3 numbers \f$(a, b, c)\f$ . For every point in one of the two images of a stereo pair, the function finds the equation of the corresponding epipolar line in the other image. -From the fundamental matrix definition (see findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second +From the fundamental matrix definition (see #findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second image for the point \f$p^{(1)}_i\f$ in the first image (when whichImage=1 ) is computed as: \f[l^{(2)}_i = F p^{(1)}_i\f] @@ -3047,7 +3047,7 @@ CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal, int maxSpeckleSize, double maxDiff, InputOutputArray buf = noArray() ); -//! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify()) +//! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by #stereoRectify) CV_EXPORTS_W Rect getValidDisparityROI( Rect roi1, Rect roi2, int minDisparity, int numberOfDisparities, int blockSize ); @@ -3112,7 +3112,7 @@ sd( \texttt{pt1} , \texttt{pt2} )= ((\texttt{F}^t \cdot \texttt{pt2})(0))^2 + ((\texttt{F}^t \cdot \texttt{pt2})(1))^2} \f] -The fundamental matrix may be calculated using the cv::findFundamentalMat function. See @cite HartleyZ00 11.4.3 for details. +The fundamental matrix may be calculated using the #findFundamentalMat function. See @cite HartleyZ00 11.4.3 for details. @param pt1 first homogeneous 2d point @param pt2 second homogeneous 2d point @param F fundamental matrix @@ -3172,6 +3172,33 @@ CV_EXPORTS_W int estimateAffine3D(InputArray src, InputArray dst, OutputArray out, OutputArray inliers, double ransacThreshold = 3, double confidence = 0.99); +/** @brief Computes an optimal affine transformation between two 3D point sets. + +It computes \f$R,s,t\f$ minimizing \f$\sum{i} dst_i - c \cdot R \cdot src_i \f$ +where \f$R\f$ is a 3x3 rotation matrix, \f$t\f$ is a 3x1 translation vector and \f$s\f$ is a +scalar size value. This is an implementation of the algorithm by Umeyama \cite umeyama1991least . +The estimated affine transform has a homogeneous scale which is a subclass of affine +transformations with 7 degrees of freedom. The paired point sets need to comprise at least 3 +points each. + +@param src First input 3D point set. +@param dst Second input 3D point set. +@param scale If null is passed, the scale parameter c will be assumed to be 1.0. +Else the pointed-to variable will be set to the optimal scale. +@param force_rotation If true, the returned rotation will never be a reflection. +This might be unwanted, e.g. when optimizing a transform between a right- and a +left-handed coordinate system. +@return 3D affine transformation matrix \f$3 \times 4\f$ of the form +\f[T = +\begin{bmatrix} +R & t\\ +\end{bmatrix} +\f] + + */ +CV_EXPORTS_W cv::Mat estimateAffine3D(InputArray src, InputArray dst, + CV_OUT double* scale = nullptr, bool force_rotation = true); + /** @brief Computes an optimal translation between two 3D point sets. * * It computes @@ -3379,10 +3406,10 @@ CV_EXPORTS_W int decomposeHomographyMat(InputArray H, @param beforePoints Vector of (rectified) visible reference points before the homography is applied @param afterPoints Vector of (rectified) visible reference points after the homography is applied @param possibleSolutions Vector of int indices representing the viable solution set after filtering -@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the findHomography function +@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the #findHomography function -This function is intended to filter the output of the decomposeHomographyMat based on additional -information as described in @cite Malis . The summary of the method: the decomposeHomographyMat function +This function is intended to filter the output of the #decomposeHomographyMat based on additional +information as described in @cite Malis . The summary of the method: the #decomposeHomographyMat function returns 2 unique solutions and their "opposites" for a total of 4 solutions. If we have access to the sets of points visible in the camera frame before and after the homography transformation is applied, we can determine which are the true potential solutions and which are the opposites by verifying which @@ -3620,7 +3647,7 @@ CV_EXPORTS_W void undistort( InputArray src, OutputArray dst, /** @brief Computes the undistortion and rectification transformation map. The function computes the joint undistortion and rectification transformation and represents the -result in the form of maps for remap. The undistorted image looks like original, as if it is +result in the form of maps for #remap. The undistorted image looks like original, as if it is captured with a camera using the camera matrix =newCameraMatrix and zero distortion. In case of a monocular camera, newCameraMatrix is usually equal to cameraMatrix, or it can be computed by #getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera, @@ -3630,7 +3657,7 @@ Also, this new camera is oriented differently in the coordinate space, according example, helps to align two heads of a stereo camera so that the epipolar lines on both images become horizontal and have the same y- coordinate (in case of a horizontally aligned stereo camera). -The function actually builds the maps for the inverse mapping algorithm that is used by remap. That +The function actually builds the maps for the inverse mapping algorithm that is used by #remap. That is, for each pixel \f$(u, v)\f$ in the destination (corrected and rectified) image, the function computes the corresponding coordinates in the source image (that is, in the original image from camera). The following process is applied: @@ -3658,7 +3685,7 @@ where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x are the distortion coefficients. In case of a stereo camera, this function is called twice: once for each camera head, after -stereoRectify, which in its turn is called after #stereoCalibrate. But if the stereo camera +#stereoRectify, which in its turn is called after #stereoCalibrate. But if the stereo camera was not calibrated, it is still possible to compute the rectification transformations directly from the fundamental matrix using #stereoRectifyUncalibrated. For each camera, the function computes homography H as the rectification transformation in a pixel domain, not a rotation matrix R in 3D @@ -3684,6 +3711,77 @@ void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2); +/** @brief Computes the projection and inverse-rectification transformation map. In essense, this is the inverse of +#initUndistortRectifyMap to accomodate stereo-rectification of projectors ('inverse-cameras') in projector-camera pairs. + +The function computes the joint projection and inverse rectification transformation and represents the +result in the form of maps for #remap. The projected image looks like a distorted version of the original which, +once projected by a projector, should visually match the original. In case of a monocular camera, newCameraMatrix +is usually equal to cameraMatrix, or it can be computed by +#getOptimalNewCameraMatrix for a better control over scaling. In case of a projector-camera pair, +newCameraMatrix is normally set to P1 or P2 computed by #stereoRectify . + +The projector is oriented differently in the coordinate space, according to R. In case of projector-camera pairs, +this helps align the projector (in the same manner as #initUndistortRectifyMap for the camera) to create a stereo-rectified pair. This +allows epipolar lines on both images to become horizontal and have the same y-coordinate (in case of a horizontally aligned projector-camera pair). + +The function builds the maps for the inverse mapping algorithm that is used by #remap. That +is, for each pixel \f$(u, v)\f$ in the destination (projected and inverse-rectified) image, the function +computes the corresponding coordinates in the source image (that is, in the original digital image). The following process is applied: + +\f[ +\begin{array}{l} +\text{newCameraMatrix}\\ +x \leftarrow (u - {c'}_x)/{f'}_x \\ +y \leftarrow (v - {c'}_y)/{f'}_y \\ + +\\\text{Undistortion} +\\\scriptsize{\textit{though equation shown is for radial undistortion, function implements cv::undistortPoints()}}\\ +r^2 \leftarrow x^2 + y^2 \\ +\theta \leftarrow \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}\\ +x' \leftarrow \frac{x}{\theta} \\ +y' \leftarrow \frac{y}{\theta} \\ + +\\\text{Rectification}\\ +{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\ +x'' \leftarrow X/W \\ +y'' \leftarrow Y/W \\ + +\\\text{cameraMatrix}\\ +map_x(u,v) \leftarrow x'' f_x + c_x \\ +map_y(u,v) \leftarrow y'' f_y + c_y +\end{array} +\f] +where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ +are the distortion coefficients vector distCoeffs. + +In case of a stereo-rectified projector-camera pair, this function is called for the projector while #initUndistortRectifyMap is called for the camera head. +This is done after #stereoRectify, which in turn is called after #stereoCalibrate. If the projector-camera pair +is not calibrated, it is still possible to compute the rectification transformations directly from +the fundamental matrix using #stereoRectifyUncalibrated. For the projector and camera, the function computes +homography H as the rectification transformation in a pixel domain, not a rotation matrix R in 3D +space. R can be computed from H as +\f[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\f] +where cameraMatrix can be chosen arbitrarily. + +@param cameraMatrix Input camera matrix \f$A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ +of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. +@param R Optional rectification transformation in the object space (3x3 matrix). R1 or R2, +computed by #stereoRectify can be passed here. If the matrix is empty, the identity transformation +is assumed. +@param newCameraMatrix New camera matrix \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$. +@param size Distorted image size. +@param m1type Type of the first output map. Can be CV_32FC1, CV_32FC2 or CV_16SC2, see #convertMaps +@param map1 The first output map for #remap. +@param map2 The second output map for #remap. + */ +CV_EXPORTS_W +void initInverseRectificationMap( InputArray cameraMatrix, InputArray distCoeffs, + InputArray R, InputArray newCameraMatrix, + const Size& size, int m1type, OutputArray map1, OutputArray map2 ); + //! initializes maps for #remap for wide-angle CV_EXPORTS float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs, @@ -3730,7 +3828,7 @@ Mat getDefaultNewCameraMatrix(InputArray cameraMatrix, Size imgsize = Size(), The function is similar to #undistort and #initUndistortRectifyMap but it operates on a sparse set of points instead of a raster image. Also the function performs a reverse transformation -to projectPoints. In case of a 3D object, it does not reconstruct its 3D coordinates, but for a +to #projectPoints. In case of a 3D object, it does not reconstruct its 3D coordinates, but for a planar object, it does, up to a translation vector, if the proper R is specified. For each observed point coordinate \f$(u, v)\f$ the function computes: @@ -3840,7 +3938,7 @@ namespace fisheye @param distorted Output array of image points, 1xN/Nx1 2-channel, or vector\ . Note that the function assumes the camera intrinsic matrix of the undistorted points to be identity. - This means if you want to transform back points undistorted with undistortPoints() you have to + This means if you want to transform back points undistorted with #fisheye::undistortPoints you have to multiply them with \f$P^{-1}\f$. */ CV_EXPORTS_W void distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0); @@ -3859,7 +3957,7 @@ namespace fisheye CV_EXPORTS_W void undistortPoints(InputArray distorted, OutputArray undistorted, InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray()); - /** @brief Computes undistortion and rectification maps for image transform by cv::remap(). If D is empty zero + /** @brief Computes undistortion and rectification maps for image transform by #remap. If D is empty zero distortion is used, if R or P is empty identity matrixes are used. @param K Camera intrinsic matrix \f$cameramatrix{K}\f$. @@ -3868,7 +3966,7 @@ namespace fisheye 1-channel or 1x1 3-channel @param P New camera intrinsic matrix (3x3) or new projection matrix (3x4) @param size Undistorted image size. - @param m1type Type of the first output map that can be CV_32FC1 or CV_16SC2 . See convertMaps() + @param m1type Type of the first output map that can be CV_32FC1 or CV_16SC2 . See #convertMaps for details. @param map1 The first output map. @param map2 The second output map. @@ -3888,14 +3986,14 @@ namespace fisheye The function transforms an image to compensate radial and tangential lens distortion. - The function is simply a combination of fisheye::initUndistortRectifyMap (with unity R ) and remap + The function is simply a combination of #fisheye::initUndistortRectifyMap (with unity R ) and #remap (with bilinear interpolation). See the former function for details of the transformation being performed. See below the results of undistortImage. - a\) result of undistort of perspective camera model (all possible coefficients (k_1, k_2, k_3, k_4, k_5, k_6) of distortion were optimized under calibration) - - b\) result of fisheye::undistortImage of fisheye camera model (all possible coefficients (k_1, k_2, + - b\) result of #fisheye::undistortImage of fisheye camera model (all possible coefficients (k_1, k_2, k_3, k_4) of fisheye distortion were optimized under calibration) - c\) original image was captured with fisheye lens @@ -3985,7 +4083,7 @@ optimization. It is the \f$max(width,height)/\pi\f$ or the provided \f$f_x\f$, \ horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the useful image area. @param newImageSize New image resolution after rectification. The same size should be passed to - initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0) + #initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0) is passed (default), it is set to the original imageSize . Setting it to larger value can help you preserve details in the original image, especially when there is a big radial distortion. @param balance Sets the new focal length in range between the min focal length and the max focal diff --git a/modules/calib3d/perf/perf_undistort.cpp b/modules/calib3d/perf/perf_undistort.cpp index 5372aaea9220..e15d2aefe3a1 100644 --- a/modules/calib3d/perf/perf_undistort.cpp +++ b/modules/calib3d/perf/perf_undistort.cpp @@ -16,4 +16,15 @@ PERF_TEST(Undistort, InitUndistortMap) SANITY_CHECK_NOTHING(); } +PERF_TEST(Undistort, DISABLED_InitInverseRectificationMap) +{ + Size size_w_h(512 + 3, 512); + Mat k(3, 3, CV_32FC1); + Mat d(1, 14, CV_64FC1); + Mat dst(size_w_h, CV_32FC2); + declare.in(k, d, WARMUP_RNG).out(dst); + TEST_CYCLE() initInverseRectificationMap(k, d, noArray(), k, size_w_h, CV_32FC2, dst, noArray()); + SANITY_CHECK_NOTHING(); +} + } // namespace diff --git a/modules/calib3d/src/chessboard.cpp b/modules/calib3d/src/chessboard.cpp index dbc47722cba9..18e2605f53b5 100644 --- a/modules/calib3d/src/chessboard.cpp +++ b/modules/calib3d/src/chessboard.cpp @@ -3924,7 +3924,7 @@ bool findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size, { meta_.create(int(board.rowCount()),int(board.colCount()),CV_8UC1); cv::Mat meta = meta_.getMat(); - meta = 0; + meta.setTo(cv::Scalar::all(0)); for(int row =0;row < meta.rows-1;++row) { for(int col=0;col< meta.cols-1;++col) diff --git a/modules/calib3d/src/ptsetreg.cpp b/modules/calib3d/src/ptsetreg.cpp index 6bd3b16c32f6..5c91fff037cc 100644 --- a/modules/calib3d/src/ptsetreg.cpp +++ b/modules/calib3d/src/ptsetreg.cpp @@ -900,6 +900,86 @@ int estimateAffine3D(InputArray _from, InputArray _to, return createRANSACPointSetRegistrator(makePtr(), 4, ransacThreshold, confidence)->run(dFrom, dTo, _out, _inliers); } +Mat estimateAffine3D(InputArray _from, InputArray _to, + CV_OUT double* _scale, bool force_rotation) +{ + CV_INSTRUMENT_REGION(); + Mat from = _from.getMat(), to = _to.getMat(); + int count = from.checkVector(3); + + CV_CheckGE(count, 3, "Umeyama algorithm needs at least 3 points for affine transformation estimation."); + CV_CheckEQ(to.checkVector(3), count, "Point sets need to have the same size"); + from = from.reshape(1, count); + to = to.reshape(1, count); + if(from.type() != CV_64F) + from.convertTo(from, CV_64F); + if(to.type() != CV_64F) + to.convertTo(to, CV_64F); + + const double one_over_n = 1./count; + + const auto colwise_mean = [one_over_n](const Mat& m) + { + Mat my; + reduce(m, my, 0, REDUCE_SUM, CV_64F); + return my * one_over_n; + }; + + const auto demean = [count](const Mat& A, const Mat& mean) + { + Mat A_centered = Mat::zeros(count, 3, CV_64F); + for(int i = 0; i < count; i++) + { + A_centered.row(i) = A.row(i) - mean; + } + return A_centered; + }; + + Mat from_mean = colwise_mean(from); + Mat to_mean = colwise_mean(to); + + Mat from_centered = demean(from, from_mean); + Mat to_centered = demean(to, to_mean); + + Mat cov = to_centered.t() * from_centered * one_over_n; + + Mat u,d,vt; + SVD::compute(cov, d, u, vt, SVD::MODIFY_A | SVD::FULL_UV); + + CV_CheckGE(countNonZero(d), 2, "Points cannot be colinear"); + + Mat S = Mat::eye(3, 3, CV_64F); + // det(d) can only ever be >=0, so we can always use this here (compared to the original formula by Umeyama) + if (force_rotation && (determinant(u) * determinant(vt) < 0)) + { + S.at(2, 2) = -1; + } + Mat rmat = u*S*vt; + + double scale = 1.0; + if (_scale) + { + double var_from = 0.; + scale = 0.; + for(int i = 0; i < 3; i++) + { + var_from += norm(from_centered.col(i), NORM_L2SQR); + scale += d.at(i, 0) * S.at(i, i); + } + double inverse_var = count / var_from; + scale *= inverse_var; + *_scale = scale; + } + Mat new_to = scale * rmat * from_mean.t(); + + Mat transform; + transform.create(3, 4, CV_64F); + Mat r_part(transform(Rect(0, 0, 3, 3))); + rmat.copyTo(r_part); + transform.col(3) = to_mean.t() - new_to; + return transform; +} + int estimateTranslation3D(InputArray _from, InputArray _to, OutputArray _out, OutputArray _inliers, double ransacThreshold, double confidence) diff --git a/modules/calib3d/src/undistort.dispatch.cpp b/modules/calib3d/src/undistort.dispatch.cpp index 2dd52037a959..146befd955f0 100644 --- a/modules/calib3d/src/undistort.dispatch.cpp +++ b/modules/calib3d/src/undistort.dispatch.cpp @@ -164,6 +164,125 @@ void initUndistortRectifyMap( InputArray _cameraMatrix, InputArray _distCoeffs, fx, fy, k1, k2, p1, p2, k3, k4, k5, k6, s1, s2, s3, s4)); } +void initInverseRectificationMap( InputArray _cameraMatrix, InputArray _distCoeffs, + InputArray _matR, InputArray _newCameraMatrix, + const Size& size, int m1type, OutputArray _map1, OutputArray _map2 ) +{ + // Parameters + Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); + Mat matR = _matR.getMat(), newCameraMatrix = _newCameraMatrix.getMat(); + + // Check m1type validity + if( m1type <= 0 ) + m1type = CV_16SC2; + CV_Assert( m1type == CV_16SC2 || m1type == CV_32FC1 || m1type == CV_32FC2 ); + + // Init Maps + _map1.create( size, m1type ); + Mat map1 = _map1.getMat(), map2; + if( m1type != CV_32FC2 ) + { + _map2.create( size, m1type == CV_16SC2 ? CV_16UC1 : CV_32FC1 ); + map2 = _map2.getMat(); + } + else { + _map2.release(); + } + + // Init camera intrinsics + Mat_ A = Mat_(cameraMatrix), Ar; + if( !newCameraMatrix.empty() ) + Ar = Mat_(newCameraMatrix); + else + Ar = getDefaultNewCameraMatrix( A, size, true ); + CV_Assert( A.size() == Size(3,3) ); + CV_Assert( Ar.size() == Size(3,3) || Ar.size() == Size(4, 3)); + + // Init rotation matrix + Mat_ R = Mat_::eye(3, 3); + if( !matR.empty() ) + { + R = Mat_(matR); + //Note, do not inverse + } + CV_Assert( Size(3,3) == R.size() ); + + // Init distortion vector + if( !distCoeffs.empty() ){ + distCoeffs = Mat_(distCoeffs); + + // Fix distortion vector orientation + if( distCoeffs.rows != 1 && !distCoeffs.isContinuous() ) { + distCoeffs = distCoeffs.t(); + } + } + + // Validate distortion vector size + CV_Assert( distCoeffs.empty() || // Empty allows cv::undistortPoints to skip distortion + distCoeffs.size() == Size(1, 4) || distCoeffs.size() == Size(4, 1) || + distCoeffs.size() == Size(1, 5) || distCoeffs.size() == Size(5, 1) || + distCoeffs.size() == Size(1, 8) || distCoeffs.size() == Size(8, 1) || + distCoeffs.size() == Size(1, 12) || distCoeffs.size() == Size(12, 1) || + distCoeffs.size() == Size(1, 14) || distCoeffs.size() == Size(14, 1)); + + // Create objectPoints + std::vector p2i_objPoints; + std::vector p2f_objPoints; + for (int r = 0; r < size.height; r++) + { + for (int c = 0; c < size.width; c++) + { + p2i_objPoints.push_back(cv::Point2i(c, r)); + p2f_objPoints.push_back(cv::Point2f(static_cast(c), static_cast(r))); + } + } + + // Undistort + std::vector p2f_objPoints_undistorted; + undistortPoints( + p2f_objPoints, + p2f_objPoints_undistorted, + A, + distCoeffs, + cv::Mat::eye(cv::Size(3, 3), CV_64FC1), // R + cv::Mat::eye(cv::Size(3, 3), CV_64FC1) // P = New K + ); + + // Rectify + std::vector p2f_sourcePoints_pinHole; + perspectiveTransform( + p2f_objPoints_undistorted, + p2f_sourcePoints_pinHole, + R + ); + + // Project points back to camera coordinates. + std::vector p2f_sourcePoints; + undistortPoints( + p2f_sourcePoints_pinHole, + p2f_sourcePoints, + cv::Mat::eye(cv::Size(3, 3), CV_32FC1), // K + cv::Mat::zeros(cv::Size(1, 4), CV_32FC1), // Distortion + cv::Mat::eye(cv::Size(3, 3), CV_32FC1), // R + Ar // New K + ); + + // Copy to map + if (m1type == CV_16SC2) { + for (size_t i=0; i < p2i_objPoints.size(); i++) { + map1.at(p2i_objPoints[i].y, p2i_objPoints[i].x) = Vec2s(saturate_cast(p2f_sourcePoints[i].x), saturate_cast(p2f_sourcePoints[i].y)); + } + } else if (m1type == CV_32FC2) { + for (size_t i=0; i < p2i_objPoints.size(); i++) { + map1.at(p2i_objPoints[i].y, p2i_objPoints[i].x) = Vec2f(p2f_sourcePoints[i]); + } + } else { // m1type == CV_32FC1 + for (size_t i=0; i < p2i_objPoints.size(); i++) { + map1.at(p2i_objPoints[i].y, p2i_objPoints[i].x) = p2f_sourcePoints[i].x; + map2.at(p2i_objPoints[i].y, p2i_objPoints[i].x) = p2f_sourcePoints[i].y; + } + } +} void undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix, InputArray _distCoeffs, InputArray _newCameraMatrix ) diff --git a/modules/calib3d/test/test_affine3d_estimator.cpp b/modules/calib3d/test/test_affine3d_estimator.cpp index 521b01ac08a8..3f1b50e5f262 100644 --- a/modules/calib3d/test/test_affine3d_estimator.cpp +++ b/modules/calib3d/test/test_affine3d_estimator.cpp @@ -201,4 +201,25 @@ TEST(Calib3d_EstimateAffine3D, regression_16007) EXPECT_EQ(1, res); } +TEST(Calib3d_EstimateAffine3D, umeyama_3_pt) +{ + std::vector points = {{{0.80549149, 0.8225781, 0.79949521}, + {0.28906756, 0.57158557, 0.9864789}, + {0.58266182, 0.65474983, 0.25078834}}}; + cv::Mat R = (cv::Mat_(3,3) << 0.9689135, -0.0232753, 0.2463025, + 0.0236362, 0.9997195, 0.0014915, + -0.2462682, 0.0043765, 0.9691918); + cv::Vec3d t(1., 2., 3.); + cv::Affine3d transform(R, t); + std::vector transformed_points(points.size()); + std::transform(points.begin(), points.end(), transformed_points.begin(), [transform](const cv::Vec3d v){return transform * v;}); + double scale; + cv::Mat trafo_est = estimateAffine3D(points, transformed_points, &scale); + Mat R_est(trafo_est(Rect(0, 0, 3, 3))); + EXPECT_LE(cvtest::norm(R_est, R, NORM_INF), 1e-6); + Vec3d t_est = trafo_est.col(3); + EXPECT_LE(cvtest::norm(t_est, t, NORM_INF), 1e-6); + EXPECT_NEAR(scale, 1.0, 1e-6); +} + }} // namespace diff --git a/modules/calib3d/test/test_undistort.cpp b/modules/calib3d/test/test_undistort.cpp index c1ec2063ee04..ea1a95207954 100644 --- a/modules/calib3d/test/test_undistort.cpp +++ b/modules/calib3d/test/test_undistort.cpp @@ -719,11 +719,281 @@ double CV_InitUndistortRectifyMapTest::get_success_error_level( int /*test_case_ return 8; } +//------------------------------------------------------ + +class CV_InitInverseRectificationMapTest : public cvtest::ArrayTest +{ +public: + CV_InitInverseRectificationMapTest(); +protected: + int prepare_test_case (int test_case_idx); + void prepare_to_validation( int test_case_idx ); + void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); + double get_success_error_level( int test_case_idx, int i, int j ); + void run_func(); + +private: + static const int MAX_X = 1024; + static const int MAX_Y = 1024; + bool zero_new_cam; + bool zero_distortion; + bool zero_R; + + cv::Size img_size; + int map_type; +}; + +CV_InitInverseRectificationMapTest::CV_InitInverseRectificationMapTest() +{ + test_array[INPUT].push_back(NULL); // camera matrix + test_array[INPUT].push_back(NULL); // distortion coeffs + test_array[INPUT].push_back(NULL); // R matrix + test_array[INPUT].push_back(NULL); // new camera matrix + test_array[OUTPUT].push_back(NULL); // inverse rectified mapx + test_array[OUTPUT].push_back(NULL); // inverse rectified mapy + test_array[REF_OUTPUT].push_back(NULL); + test_array[REF_OUTPUT].push_back(NULL); + + zero_distortion = zero_new_cam = zero_R = false; + map_type = 0; +} + +void CV_InitInverseRectificationMapTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx,sizes,types); + RNG& rng = ts->get_rng(); + //rng.next(); + + map_type = CV_32F; + types[OUTPUT][0] = types[OUTPUT][1] = types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = map_type; + + img_size.width = cvtest::randInt(rng) % MAX_X + 1; + img_size.height = cvtest::randInt(rng) % MAX_Y + 1; + + types[INPUT][0] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + types[INPUT][3] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + + sizes[OUTPUT][0] = sizes[OUTPUT][1] = sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = img_size; + sizes[INPUT][0] = sizes[INPUT][2] = sizes[INPUT][3] = cvSize(3,3); + + Size dsize; + + if (cvtest::randInt(rng)%2) + { + if (cvtest::randInt(rng)%2) + { + dsize = Size(1,4); + } + else + { + dsize = Size(1,5); + } + } + else + { + if (cvtest::randInt(rng)%2) + { + dsize = Size(4,1); + } + else + { + dsize = Size(5,1); + } + } + sizes[INPUT][1] = dsize; +} + + +int CV_InitInverseRectificationMapTest::prepare_test_case(int test_case_idx) +{ + RNG& rng = ts->get_rng(); + int code = cvtest::ArrayTest::prepare_test_case( test_case_idx ); + + if (code <= 0) + return code; + + int dist_size = test_mat[INPUT][1].cols > test_mat[INPUT][1].rows ? test_mat[INPUT][1].cols : test_mat[INPUT][1].rows; + double cam[9] = {0,0,0,0,0,0,0,0,1}; + vector dist(dist_size); + vector new_cam(test_mat[INPUT][3].cols * test_mat[INPUT][3].rows); + + Mat _camera(3,3,CV_64F,cam); + Mat _distort(test_mat[INPUT][1].size(),CV_64F,&dist[0]); + Mat _new_cam(test_mat[INPUT][3].size(),CV_64F,&new_cam[0]); + + //Generating camera matrix + double sz = MAX(img_size.width,img_size.height); + double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7; + cam[2] = (img_size.width - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + cam[5] = (img_size.height - 1)*0.5 + cvtest::randReal(rng)*10 - 5; + cam[0] = sz/(0.9 - cvtest::randReal(rng)*0.6); + cam[4] = aspect_ratio*cam[0]; + + //Generating distortion coeffs + dist[0] = cvtest::randReal(rng)*0.06 - 0.03; + dist[1] = cvtest::randReal(rng)*0.06 - 0.03; + if( dist[0]*dist[1] > 0 ) + dist[1] = -dist[1]; + if( cvtest::randInt(rng)%4 != 0 ) + { + dist[2] = cvtest::randReal(rng)*0.004 - 0.002; + dist[3] = cvtest::randReal(rng)*0.004 - 0.002; + if (dist_size > 4) + dist[4] = cvtest::randReal(rng)*0.004 - 0.002; + } + else + { + dist[2] = dist[3] = 0; + if (dist_size > 4) + dist[4] = 0; + } + + //Generating new camera matrix + _new_cam = Scalar::all(0); + new_cam[8] = 1; + + // If P == K + //new_cam[0] = cam[0]; + //new_cam[4] = cam[4]; + //new_cam[2] = cam[2]; + //new_cam[5] = cam[5]; + + // If P != K + new_cam[0] = cam[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[0]; //10% + new_cam[4] = cam[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*cam[4]; //10% + new_cam[2] = cam[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.width; //15% + new_cam[5] = cam[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*img_size.height; //15% + + //Generating R matrix + Mat _rot(3,3,CV_64F); + Mat rotation(1,3,CV_64F); + rotation.at(0) = CV_PI/8*(cvtest::randReal(rng) - (double)0.5); // phi + rotation.at(1) = CV_PI/8*(cvtest::randReal(rng) - (double)0.5); // ksi + rotation.at(2) = CV_PI/3*(cvtest::randReal(rng) - (double)0.5); //khi + cvtest::Rodrigues(rotation, _rot); + + //cvSetIdentity(_rot); + //copying data + cvtest::convert( _camera, test_mat[INPUT][0], test_mat[INPUT][0].type()); + cvtest::convert( _distort, test_mat[INPUT][1], test_mat[INPUT][1].type()); + cvtest::convert( _rot, test_mat[INPUT][2], test_mat[INPUT][2].type()); + cvtest::convert( _new_cam, test_mat[INPUT][3], test_mat[INPUT][3].type()); + + zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true; + zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true; + zero_R = (cvtest::randInt(rng)%2) == 0 ? false : true; + + return code; +} + +void CV_InitInverseRectificationMapTest::prepare_to_validation(int/* test_case_idx*/) +{ + // Configure Parameters + Mat _a0 = test_mat[INPUT][0]; + Mat _d0 = zero_distortion ? cv::Mat() : test_mat[INPUT][1]; + Mat _R0 = zero_R ? cv::Mat() : test_mat[INPUT][2]; + Mat _new_cam0 = zero_new_cam ? test_mat[INPUT][0] : test_mat[INPUT][3]; + Mat _mapx(img_size, CV_32F), _mapy(img_size, CV_32F); + + double a[9], d[5]={0., 0., 0., 0. , 0.}, R[9]={1., 0., 0., 0., 1., 0., 0., 0., 1.}, a1[9]; + Mat _a(3, 3, CV_64F, a), _a1(3, 3, CV_64F, a1); + Mat _d(_d0.rows,_d0.cols, CV_MAKETYPE(CV_64F,_d0.channels()),d); + Mat _R(3, 3, CV_64F, R); + double fx, fy, cx, cy, ifx, ify, cxn, cyn; + + // Camera matrix + CV_Assert(_a0.size() == Size(3, 3)); + _a0.convertTo(_a, CV_64F); + if( !_new_cam0.empty() ) + { + CV_Assert(_new_cam0.size() == Size(3, 3)); + _new_cam0.convertTo(_a1, CV_64F); + } + else + { + _a.copyTo(_a1); + } + + // Distortion + CV_Assert(_d0.empty() || + _d0.size() == Size(5, 1) || + _d0.size() == Size(1, 5) || + _d0.size() == Size(4, 1) || + _d0.size() == Size(1, 4)); + if( !_d0.empty() ) + _d0.convertTo(_d, CV_64F); + + // Rotation + if( !_R0.empty() ) + { + CV_Assert(_R0.size() == Size(3, 3)); + Mat tmp; + _R0.convertTo(_R, CV_64F); + } + + // Copy camera matrix + fx = a[0]; fy = a[4]; cx = a[2]; cy = a[5]; + + // Copy new camera matrix + ifx = a1[0]; ify = a1[4]; cxn = a1[2]; cyn = a1[5]; + + // Undistort + for( int v = 0; v < img_size.height; v++ ) + { + for( int u = 0; u < img_size.width; u++ ) + { + // Convert from image to pin-hole coordinates + double x = (u - cx)/fx; + double y = (v - cy)/fy; + + // Undistort + double x2 = x*x, y2 = y*y; + double r2 = x2 + y2; + double cdist = 1./(1. + (d[0] + (d[1] + d[4]*r2)*r2)*r2); // (1. + (d[5] + (d[6] + d[7]*r2)*r2)*r2) == 1 as d[5-7]=0; + double x_ = (x - (d[2]*2.*x*y + d[3]*(r2 + 2.*x2)))*cdist; + double y_ = (y - (d[3]*2.*x*y + d[2]*(r2 + 2.*y2)))*cdist; + + // Rectify + double X = R[0]*x_ + R[1]*y_ + R[2]; + double Y = R[3]*x_ + R[4]*y_ + R[5]; + double Z = R[6]*x_ + R[7]*y_ + R[8]; + double x__ = X/Z; + double y__ = Y/Z; + + // Convert from pin-hole to image coordinates + _mapy.at(v, u) = (float)(y__*ify + cyn); + _mapx.at(v, u) = (float)(x__*ifx + cxn); + } + } + + // Convert + _mapx.convertTo(test_mat[REF_OUTPUT][0], test_mat[REF_OUTPUT][0].type()); + _mapy.convertTo(test_mat[REF_OUTPUT][1], test_mat[REF_OUTPUT][0].type()); +} + +void CV_InitInverseRectificationMapTest::run_func() +{ + cv::Mat camera_mat = test_mat[INPUT][0]; + cv::Mat dist = zero_distortion ? cv::Mat() : test_mat[INPUT][1]; + cv::Mat R = zero_R ? cv::Mat() : test_mat[INPUT][2]; + cv::Mat new_cam = zero_new_cam ? cv::Mat() : test_mat[INPUT][3]; + cv::Mat& mapx = test_mat[OUTPUT][0], &mapy = test_mat[OUTPUT][1]; + cv::initInverseRectificationMap(camera_mat,dist,R,new_cam,img_size,map_type,mapx,mapy); +} + +double CV_InitInverseRectificationMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ ) +{ + return 8; +} + ////////////////////////////////////////////////////////////////////////////////////////////////////// TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest test; test.safe_run(); } TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); } TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); } +TEST(DISABLED_Calib3d_InitInverseRectificationMap, accuracy) { CV_InitInverseRectificationMapTest test; test.safe_run(); } ////////////////////////////// undistort ///////////////////////////////// @@ -1537,4 +1807,78 @@ TEST(Calib3d_initUndistortRectifyMap, regression_14467) EXPECT_LE(cvtest::norm(dst, mesh_uv, NORM_INF), 1e-3); } +TEST(Calib3d_initInverseRectificationMap, regression_20165) +{ + Size size_w_h(1280, 800); + Mat dst(size_w_h, CV_32FC2); // Reference for validation + Mat mapxy; // Output of initInverseRectificationMap() + + // Camera Matrix + double k[9]={ + 1.5393951443032472e+03, 0., 6.7491727003047140e+02, + 0., 1.5400748240626747e+03, 5.1226968329123963e+02, + 0., 0., 1. + }; + Mat _K(3, 3, CV_64F, k); + + // Distortion + // double d[5]={0,0,0,0,0}; // Zero Distortion + double d[5]={ // Non-zero distortion + -3.4134571357400023e-03, 2.9733267766101856e-03, // K1, K2 + 3.6653586399031184e-03, -3.1960714017365702e-03, // P1, P2 + 0. // K3 + }; + Mat _d(1, 5, CV_64F, d); + + // Rotation + //double R[9]={1., 0., 0., 0., 1., 0., 0., 0., 1.}; // Identity transform (none) + double R[9]={ // Random transform + 9.6625486010428052e-01, 1.6055789378989216e-02, 2.5708706103628531e-01, + -8.0300261706161002e-03, 9.9944797497929860e-01, -3.2237617614807819e-02, + -2.5746274294459848e-01, 2.9085338870243265e-02, 9.6585039165403186e-01 + }; + Mat _R(3, 3, CV_64F, R); + + // --- Validation --- // + initInverseRectificationMap(_K, _d, _R, _K, size_w_h, CV_32FC2, mapxy, noArray()); + + // Copy camera matrix + double fx, fy, cx, cy, ifx, ify, cxn, cyn; + fx = k[0]; fy = k[4]; cx = k[2]; cy = k[5]; + + // Copy new camera matrix + ifx = k[0]; ify = k[4]; cxn = k[2]; cyn = k[5]; + + // Distort Points + for( int v = 0; v < size_w_h.height; v++ ) + { + for( int u = 0; u < size_w_h.width; u++ ) + { + // Convert from image to pin-hole coordinates + double x = (u - cx)/fx; + double y = (v - cy)/fy; + + // Undistort + double x2 = x*x, y2 = y*y; + double r2 = x2 + y2; + double cdist = 1./(1. + (d[0] + (d[1] + d[4]*r2)*r2)*r2); // (1. + (d[5] + (d[6] + d[7]*r2)*r2)*r2) == 1 as d[5-7]=0; + double x_ = (x - (d[2]*2.*x*y + d[3]*(r2 + 2.*x2)))*cdist; + double y_ = (y - (d[3]*2.*x*y + d[2]*(r2 + 2.*y2)))*cdist; + + // Rectify + double X = R[0]*x_ + R[1]*y_ + R[2]; + double Y = R[3]*x_ + R[4]*y_ + R[5]; + double Z = R[6]*x_ + R[7]*y_ + R[8]; + double x__ = X/Z; + double y__ = Y/Z; + + // Convert from pin-hole to image coordinates + dst.at(v, u) = Vec2f((float)(x__*ifx + cxn), (float)(y__*ify + cyn)); + } + } + + // Check Result + EXPECT_LE(cvtest::norm(dst, mapxy, NORM_INF), 2e-1); +} + }} // namespace diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index b2797ab31fc1..6a969e5fc358 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -153,6 +153,10 @@ if(OPENCV_CORE_EXCLUDE_C_API) ocv_target_compile_definitions(${the_module} PRIVATE "OPENCV_EXCLUDE_C_API=1") endif() +if(OPENCV_DISABLE_THREAD_SUPPORT) + ocv_target_compile_definitions(${the_module} PUBLIC "OPENCV_DISABLE_THREAD_SUPPORT=1") +endif() + if(HAVE_HPX) ocv_target_link_libraries(${the_module} LINK_PRIVATE "${HPX_LIBRARIES}") endif() diff --git a/modules/core/include/opencv2/core/cv_cpu_dispatch.h b/modules/core/include/opencv2/core/cv_cpu_dispatch.h index fe15e51e4e85..8365b10ba9fd 100644 --- a/modules/core/include/opencv2/core/cv_cpu_dispatch.h +++ b/modules/core/include/opencv2/core/cv_cpu_dispatch.h @@ -142,6 +142,11 @@ # define CV_NEON 1 #endif +#if defined(__riscv) && defined(__riscv_vector) && defined(__riscv_vector_071) +# include +# define CV_RVV071 1 +#endif + #if defined(__ARM_NEON__) || defined(__aarch64__) # include #endif @@ -338,6 +343,10 @@ struct VZeroUpperGuard { # define CV_NEON 0 #endif +#ifndef CV_RVV071 +# define CV_RVV071 0 +#endif + #ifndef CV_VSX # define CV_VSX 0 #endif diff --git a/modules/core/include/opencv2/core/cvdef.h b/modules/core/include/opencv2/core/cvdef.h index ebb1f65eb788..7f510748af13 100644 --- a/modules/core/include/opencv2/core/cvdef.h +++ b/modules/core/include/opencv2/core/cvdef.h @@ -271,6 +271,8 @@ namespace cv { #define CV_CPU_MSA 150 +#define CV_CPU_RISCVV 170 + #define CV_CPU_VSX 200 #define CV_CPU_VSX3 201 @@ -325,6 +327,8 @@ enum CpuFeatures { CPU_MSA = 150, + CPU_RISCVV = 170, + CPU_VSX = 200, CPU_VSX3 = 201, diff --git a/modules/core/include/opencv2/core/hal/intrin.hpp b/modules/core/include/opencv2/core/hal/intrin.hpp index 6f5b8e17885b..ac331f2154de 100644 --- a/modules/core/include/opencv2/core/hal/intrin.hpp +++ b/modules/core/include/opencv2/core/hal/intrin.hpp @@ -200,7 +200,7 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE; # undef CV_RVV #endif -#if (CV_SSE2 || CV_NEON || CV_VSX || CV_MSA || CV_WASM_SIMD || CV_RVV) && !defined(CV_FORCE_SIMD128_CPP) +#if (CV_SSE2 || CV_NEON || CV_VSX || CV_MSA || CV_WASM_SIMD || CV_RVV071 || CV_RVV) && !defined(CV_FORCE_SIMD128_CPP) #define CV__SIMD_FORWARD 128 #include "opencv2/core/hal/intrin_forward.hpp" #endif @@ -214,6 +214,10 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE; #include "opencv2/core/hal/intrin_neon.hpp" +#elif CV_RVV071 && !defined(CV_FORCE_SIMD128_CPP) +#define CV_SIMD128_CPP 0 +#include "opencv2/core/hal/intrin_rvv071.hpp" + #elif CV_VSX && !defined(CV_FORCE_SIMD128_CPP) #include "opencv2/core/hal/intrin_vsx.hpp" diff --git a/modules/core/include/opencv2/core/hal/intrin_neon.hpp b/modules/core/include/opencv2/core/hal/intrin_neon.hpp index 785648575a60..e17972a3fc4a 100644 --- a/modules/core/include/opencv2/core/hal/intrin_neon.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_neon.hpp @@ -538,49 +538,81 @@ inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b, v_int16x8& c, v_int16x8& d) { c.val = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val)); +#if CV_NEON_AARCH64 + d.val = vmull_high_s8(a.val, b.val); +#else // #if CV_NEON_AARCH64 d.val = vmull_s8(vget_high_s8(a.val), vget_high_s8(b.val)); +#endif // #if CV_NEON_AARCH64 } inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b, v_uint16x8& c, v_uint16x8& d) { c.val = vmull_u8(vget_low_u8(a.val), vget_low_u8(b.val)); +#if CV_NEON_AARCH64 + d.val = vmull_high_u8(a.val, b.val); +#else // #if CV_NEON_AARCH64 d.val = vmull_u8(vget_high_u8(a.val), vget_high_u8(b.val)); +#endif // #if CV_NEON_AARCH64 } inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b, v_int32x4& c, v_int32x4& d) { c.val = vmull_s16(vget_low_s16(a.val), vget_low_s16(b.val)); +#if CV_NEON_AARCH64 + d.val = vmull_high_s16(a.val, b.val); +#else // #if CV_NEON_AARCH64 d.val = vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)); +#endif // #if CV_NEON_AARCH64 } inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b, v_uint32x4& c, v_uint32x4& d) { c.val = vmull_u16(vget_low_u16(a.val), vget_low_u16(b.val)); +#if CV_NEON_AARCH64 + d.val = vmull_high_u16(a.val, b.val); +#else // #if CV_NEON_AARCH64 d.val = vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val)); +#endif // #if CV_NEON_AARCH64 } inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, v_uint64x2& c, v_uint64x2& d) { c.val = vmull_u32(vget_low_u32(a.val), vget_low_u32(b.val)); +#if CV_NEON_AARCH64 + d.val = vmull_high_u32(a.val, b.val); +#else // #if CV_NEON_AARCH64 d.val = vmull_u32(vget_high_u32(a.val), vget_high_u32(b.val)); +#endif // #if CV_NEON_AARCH64 } inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b) { return v_int16x8(vcombine_s16( vshrn_n_s32(vmull_s16( vget_low_s16(a.val), vget_low_s16(b.val)), 16), - vshrn_n_s32(vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)), 16) + vshrn_n_s32( +#if CV_NEON_AARCH64 + vmull_high_s16(a.val, b.val) +#else // #if CV_NEON_AARCH64 + vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)) +#endif // #if CV_NEON_AARCH64 + , 16) )); } inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b) { return v_uint16x8(vcombine_u16( vshrn_n_u32(vmull_u16( vget_low_u16(a.val), vget_low_u16(b.val)), 16), - vshrn_n_u32(vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val)), 16) + vshrn_n_u32( +#if CV_NEON_AARCH64 + vmull_high_u16(a.val, b.val) +#else // #if CV_NEON_AARCH64 + vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val)) +#endif // #if CV_NEON_AARCH64 + , 16) )); } @@ -1254,29 +1286,56 @@ OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float64x2, double, f64) inline unsigned v_reduce_sum(const v_uint8x16& a) { +#if CV_NEON_AARCH64 + uint16_t t0 = vaddlvq_u8(a.val); + return t0; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(a.val)); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline int v_reduce_sum(const v_int8x16& a) { +#if CV_NEON_AARCH64 + int16_t t0 = vaddlvq_s8(a.val); + return t0; +#else // #if CV_NEON_AARCH64 int32x4_t t0 = vpaddlq_s16(vpaddlq_s8(a.val)); int32x2_t t1 = vpadd_s32(vget_low_s32(t0), vget_high_s32(t0)); return vget_lane_s32(vpadd_s32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sum(const v_uint16x8& a) { +#if CV_NEON_AARCH64 + uint32_t t0 = vaddlvq_u16(a.val); + return t0; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vpaddlq_u16(a.val); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline int v_reduce_sum(const v_int16x8& a) { +#if CV_NEON_AARCH64 + int32_t t0 = vaddlvq_s16(a.val); + return t0; +#else // #if CV_NEON_AARCH64 int32x4_t t0 = vpaddlq_s16(a.val); int32x2_t t1 = vpadd_s32(vget_low_s32(t0), vget_high_s32(t0)); return vget_lane_s32(vpadd_s32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } +#if CV_NEON_AARCH64 +#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + return v##vectorfunc##vq_##suffix(a.val); \ +} +#else // #if CV_NEON_AARCH64 #define OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ inline scalartype v_reduce_##func(const _Tpvec& a) \ { \ @@ -1285,12 +1344,20 @@ inline scalartype v_reduce_##func(const _Tpvec& a) \ a0 = vp##vectorfunc##_##suffix(a0, a0); \ return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \ } +#endif // #if CV_NEON_AARCH64 OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_uint8x16, uint8x8, uchar, max, max, u8) OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_uint8x16, uint8x8, uchar, min, min, u8) OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_int8x16, int8x8, schar, max, max, s8) OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(v_int8x16, int8x8, schar, min, min, s8) +#if CV_NEON_AARCH64 +#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + return v##vectorfunc##vq_##suffix(a.val); \ +} +#else // #if CV_NEON_AARCH64 #define OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ inline scalartype v_reduce_##func(const _Tpvec& a) \ { \ @@ -1298,18 +1365,27 @@ inline scalartype v_reduce_##func(const _Tpvec& a) \ a0 = vp##vectorfunc##_##suffix(a0, a0); \ return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \ } +#endif // #if CV_NEON_AARCH64 OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, ushort, max, max, u16) OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, ushort, min, min, u16) OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, max, max, s16) OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, min, min, s16) +#if CV_NEON_AARCH64 +#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + return v##vectorfunc##vq_##suffix(a.val); \ +} +#else // #if CV_NEON_AARCH64 #define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ inline scalartype v_reduce_##func(const _Tpvec& a) \ { \ _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \ return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, vget_high_##suffix(a.val)),0); \ } +#endif // #if CV_NEON_AARCH64 OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, sum, add, u32) OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, max, max, u32) @@ -1322,9 +1398,21 @@ OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, max, max, f32) OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, min, min, f32) inline uint64 v_reduce_sum(const v_uint64x2& a) -{ return vget_lane_u64(vadd_u64(vget_low_u64(a.val), vget_high_u64(a.val)),0); } +{ +#if CV_NEON_AARCH64 + return vaddvq_u64(a.val); +#else // #if CV_NEON_AARCH64 + return vget_lane_u64(vadd_u64(vget_low_u64(a.val), vget_high_u64(a.val)),0); +#endif // #if CV_NEON_AARCH64 +} inline int64 v_reduce_sum(const v_int64x2& a) -{ return vget_lane_s64(vadd_s64(vget_low_s64(a.val), vget_high_s64(a.val)),0); } +{ +#if CV_NEON_AARCH64 + return vaddvq_s64(a.val); +#else // #if CV_NEON_AARCH64 + return vget_lane_s64(vadd_s64(vget_low_s64(a.val), vget_high_s64(a.val)),0); +#endif // #if CV_NEON_AARCH64 +} #if CV_SIMD128_64F inline double v_reduce_sum(const v_float64x2& a) { @@ -1335,6 +1423,11 @@ inline double v_reduce_sum(const v_float64x2& a) inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c, const v_float32x4& d) { +#if CV_NEON_AARCH64 + float32x4_t ab = vpaddq_f32(a.val, b.val); // a0+a1 a2+a3 b0+b1 b2+b3 + float32x4_t cd = vpaddq_f32(c.val, d.val); // c0+c1 d0+d1 c2+c3 d2+d3 + return v_float32x4(vpaddq_f32(ab, cd)); // sumA sumB sumC sumD +#else // #if CV_NEON_AARCH64 float32x4x2_t ab = vtrnq_f32(a.val, b.val); float32x4x2_t cd = vtrnq_f32(c.val, d.val); @@ -1345,49 +1438,91 @@ inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, float32x4_t v1 = vcombine_f32(vget_high_f32(u0), vget_high_f32(u1)); return v_float32x4(vaddq_f32(v0, v1)); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sad(const v_uint8x16& a, const v_uint8x16& b) { +#if CV_NEON_AARCH64 + uint8x16_t t0 = vabdq_u8(a.val, b.val); + uint16_t t1 = vaddlvq_u8(t0); + return t1; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(vabdq_u8(a.val, b.val))); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sad(const v_int8x16& a, const v_int8x16& b) { +#if CV_NEON_AARCH64 + uint8x16_t t0 = vreinterpretq_u8_s8(vabdq_s8(a.val, b.val)); + uint16_t t1 = vaddlvq_u8(t0); + return t1; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(vreinterpretq_u8_s8(vabdq_s8(a.val, b.val)))); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sad(const v_uint16x8& a, const v_uint16x8& b) { +#if CV_NEON_AARCH64 + uint16x8_t t0 = vabdq_u16(a.val, b.val); + uint32_t t1 = vaddlvq_u16(t0); + return t1; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vpaddlq_u16(vabdq_u16(a.val, b.val)); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sad(const v_int16x8& a, const v_int16x8& b) { +#if CV_NEON_AARCH64 + uint16x8_t t0 = vreinterpretq_u16_s16(vabdq_s16(a.val, b.val)); + uint32_t t1 = vaddlvq_u16(t0); + return t1; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vpaddlq_u16(vreinterpretq_u16_s16(vabdq_s16(a.val, b.val))); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sad(const v_uint32x4& a, const v_uint32x4& b) { +#if CV_NEON_AARCH64 + uint32x4_t t0 = vabdq_u32(a.val, b.val); + uint32_t t1 = vaddvq_u32(t0); + return t1; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vabdq_u32(a.val, b.val); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline unsigned v_reduce_sad(const v_int32x4& a, const v_int32x4& b) { +#if CV_NEON_AARCH64 + uint32x4_t t0 = vreinterpretq_u32_s32(vabdq_s32(a.val, b.val)); + uint32_t t1 = vaddvq_u32(t0); + return t1; +#else // #if CV_NEON_AARCH64 uint32x4_t t0 = vreinterpretq_u32_s32(vabdq_s32(a.val, b.val)); uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); return vget_lane_u32(vpadd_u32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline float v_reduce_sad(const v_float32x4& a, const v_float32x4& b) { +#if CV_NEON_AARCH64 + float32x4_t t0 = vabdq_f32(a.val, b.val); + return vaddvq_f32(t0); +#else // #if CV_NEON_AARCH64 float32x4_t t0 = vabdq_f32(a.val, b.val); float32x2_t t1 = vpadd_f32(vget_low_f32(t0), vget_high_f32(t0)); return vget_lane_f32(vpadd_f32(t1, t1), 0); +#endif // #if CV_NEON_AARCH64 } inline v_uint8x16 v_popcount(const v_uint8x16& a) @@ -1409,30 +1544,54 @@ inline v_uint64x2 v_popcount(const v_int64x2& a) inline int v_signmask(const v_uint8x16& a) { +#if CV_NEON_AARCH64 + const int8x16_t signPosition = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7}; + const uint8x16_t byteOrder = {0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15}; + uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), signPosition); + uint8x16_t v1 = vqtbl1q_u8(v0, byteOrder); + uint32_t t0 = vaddlvq_u16(vreinterpretq_u16_u8(v1)); + return t0; +#else // #if CV_NEON_AARCH64 int8x8_t m0 = vcreate_s8(CV_BIG_UINT(0x0706050403020100)); uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_s8(m0, m0)); uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0))); return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8); +#endif // #if CV_NEON_AARCH64 } + inline int v_signmask(const v_int8x16& a) { return v_signmask(v_reinterpret_as_u8(a)); } inline int v_signmask(const v_uint16x8& a) { +#if CV_NEON_AARCH64 + const int16x8_t signPosition = {0,1,2,3,4,5,6,7}; + uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), signPosition); + uint32_t t0 = vaddlvq_u16(v0); + return t0; +#else // #if CV_NEON_AARCH64 int16x4_t m0 = vcreate_s16(CV_BIG_UINT(0x0003000200010000)); uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_s16(m0, m0)); uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(v0)); return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 4); +#endif // #if CV_NEON_AARCH64 } inline int v_signmask(const v_int16x8& a) { return v_signmask(v_reinterpret_as_u16(a)); } inline int v_signmask(const v_uint32x4& a) { +#if CV_NEON_AARCH64 + const int32x4_t signPosition = {0,1,2,3}; + uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), signPosition); + uint32_t t0 = vaddvq_u32(v0); + return t0; +#else // #if CV_NEON_AARCH64 int32x2_t m0 = vcreate_s32(CV_BIG_UINT(0x0000000100000000)); uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_s32(m0, m0)); uint64x2_t v1 = vpaddlq_u32(v0); return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 2); +#endif // #if CV_NEON_AARCH64 } inline int v_signmask(const v_int32x4& a) { return v_signmask(v_reinterpret_as_u32(a)); } @@ -1440,9 +1599,16 @@ inline int v_signmask(const v_float32x4& a) { return v_signmask(v_reinterpret_as_u32(a)); } inline int v_signmask(const v_uint64x2& a) { +#if CV_NEON_AARCH64 + const int64x2_t signPosition = {0,1}; + uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), signPosition); + uint64_t t0 = vaddvq_u64(v0); + return t0; +#else // #if CV_NEON_AARCH64 int64x1_t m0 = vdup_n_s64(0); uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), vcombine_s64(m0, m0)); return (int)vgetq_lane_u64(v0, 0) + ((int)vgetq_lane_u64(v0, 1) << 1); +#endif // #if CV_NEON_AARCH64 } inline int v_signmask(const v_int64x2& a) { return v_signmask(v_reinterpret_as_u64(a)); } @@ -1464,19 +1630,31 @@ inline int v_scan_forward(const v_uint64x2& a) { return trailingZeros32(v_signma inline int v_scan_forward(const v_float64x2& a) { return trailingZeros32(v_signmask(a)); } #endif -#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \ -inline bool v_check_all(const v_##_Tpvec& a) \ -{ \ - _Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \ - uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ - return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \ -} \ -inline bool v_check_any(const v_##_Tpvec& a) \ -{ \ - _Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \ - uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ - return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \ -} +#if CV_NEON_AARCH64 + #define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \ + inline bool v_check_all(const v_##_Tpvec& a) \ + { \ + return (vminvq_##suffix(a.val) >> shift) != 0; \ + } \ + inline bool v_check_any(const v_##_Tpvec& a) \ + { \ + return (vmaxvq_##suffix(a.val) >> shift) != 0; \ + } +#else // #if CV_NEON_AARCH64 + #define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \ + inline bool v_check_all(const v_##_Tpvec& a) \ + { \ + _Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \ + uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ + return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \ + } \ + inline bool v_check_any(const v_##_Tpvec& a) \ + { \ + _Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \ + uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ + return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \ + } +#endif // #if CV_NEON_AARCH64 OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint8x16, u8, 7) OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint16x8, u16, 15) @@ -1829,6 +2007,37 @@ inline v_int32x4 v_trunc(const v_float64x2& a) } #endif +#if CV_NEON_AARCH64 +#define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \ +inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \ + const v_##_Tpvec& a2, const v_##_Tpvec& a3, \ + v_##_Tpvec& b0, v_##_Tpvec& b1, \ + v_##_Tpvec& b2, v_##_Tpvec& b3) \ +{ \ + /* -- Pass 1: 64b transpose */ \ + _Tpvec##_t t0 = vreinterpretq_##suffix##32_##suffix##64( \ + vtrn1q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a0.val), \ + vreinterpretq_##suffix##64_##suffix##32(a2.val))); \ + _Tpvec##_t t1 = vreinterpretq_##suffix##32_##suffix##64( \ + vtrn1q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a1.val), \ + vreinterpretq_##suffix##64_##suffix##32(a3.val))); \ + _Tpvec##_t t2 = vreinterpretq_##suffix##32_##suffix##64( \ + vtrn2q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a0.val), \ + vreinterpretq_##suffix##64_##suffix##32(a2.val))); \ + _Tpvec##_t t3 = vreinterpretq_##suffix##32_##suffix##64( \ + vtrn2q_##suffix##64(vreinterpretq_##suffix##64_##suffix##32(a1.val), \ + vreinterpretq_##suffix##64_##suffix##32(a3.val))); \ + /* -- Pass 2: 32b transpose */ \ + b0.val = vtrn1q_##suffix##32(t0, t1); \ + b1.val = vtrn2q_##suffix##32(t0, t1); \ + b2.val = vtrn1q_##suffix##32(t2, t3); \ + b3.val = vtrn2q_##suffix##32(t2, t3); \ +} + +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u) +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s) +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f) +#else // #if CV_NEON_AARCH64 #define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \ inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \ const v_##_Tpvec& a2, const v_##_Tpvec& a3, \ @@ -1854,6 +2063,7 @@ inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \ OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u32) OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s32) OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f32) +#endif // #if CV_NEON_AARCH64 #define OPENCV_HAL_IMPL_NEON_INTERLEAVED(_Tpvec, _Tp, suffix) \ inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b) \ diff --git a/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp b/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp new file mode 100644 index 000000000000..2bdc622ffd49 --- /dev/null +++ b/modules/core/include/opencv2/core/hal/intrin_rvv071.hpp @@ -0,0 +1,2545 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +// Copyright (C) 2015, PingTouGe Semiconductor Co., Ltd., all rights reserved. + +#ifndef OPENCV_HAL_INTRIN_RISCVV_HPP +#define OPENCV_HAL_INTRIN_RISCVV_HPP + +#include +#include +#include "opencv2/core/utility.hpp" + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +#define CV_SIMD128 1 +#define CV_SIMD128_64F 1 +//////////// Types //////////// +struct v_uint8x16 +{ + typedef uchar lane_type; + enum { nlanes = 16 }; + + v_uint8x16() {} + explicit v_uint8x16(vuint8m1_t v) : val(v) {} + v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15) + { + uchar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15}; + val = (vuint8m1_t)vle_v_u8m1((unsigned char*)v, 16); + } + uchar get0() const + { + return vmv_x_s_u8m1_u8(val, 16); + } + + vuint8m1_t val; +}; + +struct v_int8x16 +{ + typedef schar lane_type; + enum { nlanes = 16 }; + + v_int8x16() {} + explicit v_int8x16(vint8m1_t v) : val(v) {} + v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15) + { + schar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15}; + val = (vint8m1_t)vle_v_i8m1((schar*)v, 16); + } + schar get0() const + { + return vmv_x_s_i8m1_i8(val, 16); + } + + vint8m1_t val; +}; + +struct v_uint16x8 +{ + typedef ushort lane_type; + enum { nlanes = 8 }; + + v_uint16x8() {} + explicit v_uint16x8(vuint16m1_t v) : val(v) {} + v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7) + { + ushort v[] = {v0, v1, v2, v3, v4, v5, v6, v7}; + val = (vuint16m1_t)vle_v_u16m1((unsigned short*)v, 8); + } + ushort get0() const + { + return vmv_x_s_u16m1_u16(val, 8); + } + + vuint16m1_t val; +}; + +struct v_int16x8 +{ + typedef short lane_type; + enum { nlanes = 8 }; + + v_int16x8() {} + explicit v_int16x8(vint16m1_t v) : val(v) {} + v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7) + { + short v[] = {v0, v1, v2, v3, v4, v5, v6, v7}; + val = (vint16m1_t)vle_v_i16m1((signed short*)v, 8); + } + short get0() const + { + return vmv_x_s_i16m1_i16(val, 8); + } + + vint16m1_t val; +}; + +struct v_uint32x4 +{ + typedef unsigned lane_type; + enum { nlanes = 4 }; + + v_uint32x4() {} + explicit v_uint32x4(vuint32m1_t v) : val(v) {} + v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) + { + unsigned v[] = {v0, v1, v2, v3}; + val = (vuint32m1_t)vle_v_u32m1((unsigned int*)v, 4); + } + unsigned get0() const + { + return vmv_x_s_u32m1_u32(val, 4); + } + + vuint32m1_t val; +}; + +struct v_int32x4 +{ + typedef int lane_type; + enum { nlanes = 4 }; + + v_int32x4() {} + explicit v_int32x4(vint32m1_t v) : val(v) {} + v_int32x4(int v0, int v1, int v2, int v3) + { + int v[] = {v0, v1, v2, v3}; + val = (vint32m1_t)vle_v_i32m1((signed int*)v, 4); + } + int get0() const + { + return vmv_x_s_i32m1_i32(val, 4); + } + vint32m1_t val; +}; + +struct v_float32x4 +{ + typedef float lane_type; + enum { nlanes = 4 }; + + v_float32x4() {} + explicit v_float32x4(vfloat32m1_t v) : val(v) {} + v_float32x4(float v0, float v1, float v2, float v3) + { + float v[] = {v0, v1, v2, v3}; + val = (vfloat32m1_t)vle_v_f32m1((float*)v, 4); + } + float get0() const + { + return vfmv_f_s_f32m1_f32(val, 4); + } + vfloat32m1_t val; +}; + +struct v_uint64x2 +{ + typedef uint64 lane_type; + enum { nlanes = 2 }; + + v_uint64x2() {} + explicit v_uint64x2(vuint64m1_t v) : val(v) {} + v_uint64x2(uint64 v0, uint64 v1) + { + uint64 v[] = {v0, v1}; + val = (vuint64m1_t)vle_v_u64m1((unsigned long*)v, 2); + } + uint64 get0() const + { + return vmv_x_s_u64m1_u64(val, 2); + } + vuint64m1_t val; +}; + +struct v_int64x2 +{ + typedef int64 lane_type; + enum { nlanes = 2 }; + + v_int64x2() {} + explicit v_int64x2(vint64m1_t v) : val(v) {} + v_int64x2(int64 v0, int64 v1) + { + int64 v[] = {v0, v1}; + val = (vint64m1_t)vle_v_i64m1((long*)v, 2); + } + int64 get0() const + { + return vmv_x_s_i64m1_i64(val, 2); + } + vint64m1_t val; +}; + +struct v_float64x2 +{ + typedef double lane_type; + enum { nlanes = 2 }; + + v_float64x2() {} + explicit v_float64x2(vfloat64m1_t v) : val(v) {} + v_float64x2(double v0, double v1) + { + double v[] = {v0, v1}; + val = (vfloat64m1_t)vle_v_f64m1((double*)v, 2); + } + double get0() const + { + return vfmv_f_s_f64m1_f64(val, 2); + } + vfloat64m1_t val; +}; + +#define OPENCV_HAL_IMPL_RISCVV_INIT(_Tpv, _Tp, suffix) \ +inline _Tp##m1_t vreinterpretq_##suffix##_##suffix(_Tp##m1_t v) { return v; } \ +inline v_uint8x16 v_reinterpret_as_u8(const v_##_Tpv& v) { return v_uint8x16((vuint8m1_t)(v.val)); } \ +inline v_int8x16 v_reinterpret_as_s8(const v_##_Tpv& v) { return v_int8x16((vint8m1_t)(v.val)); } \ +inline v_uint16x8 v_reinterpret_as_u16(const v_##_Tpv& v) { return v_uint16x8((vuint16m1_t)(v.val)); } \ +inline v_int16x8 v_reinterpret_as_s16(const v_##_Tpv& v) { return v_int16x8((vint16m1_t)(v.val)); } \ +inline v_uint32x4 v_reinterpret_as_u32(const v_##_Tpv& v) { return v_uint32x4((vuint32m1_t)(v.val)); } \ +inline v_int32x4 v_reinterpret_as_s32(const v_##_Tpv& v) { return v_int32x4((vint32m1_t)(v.val)); } \ +inline v_uint64x2 v_reinterpret_as_u64(const v_##_Tpv& v) { return v_uint64x2((vuint64m1_t)(v.val)); } \ +inline v_int64x2 v_reinterpret_as_s64(const v_##_Tpv& v) { return v_int64x2((vint64m1_t)(v.val)); } \ +inline v_float32x4 v_reinterpret_as_f32(const v_##_Tpv& v) { return v_float32x4((vfloat32m1_t)(v.val)); }\ +inline v_float64x2 v_reinterpret_as_f64(const v_##_Tpv& v) { return v_float64x2((vfloat64m1_t)(v.val)); } + + +OPENCV_HAL_IMPL_RISCVV_INIT(uint8x16, vuint8, u8) +OPENCV_HAL_IMPL_RISCVV_INIT(int8x16, vint8, s8) +OPENCV_HAL_IMPL_RISCVV_INIT(uint16x8, vuint16, u16) +OPENCV_HAL_IMPL_RISCVV_INIT(int16x8, vint16, s16) +OPENCV_HAL_IMPL_RISCVV_INIT(uint32x4, vuint32, u32) +OPENCV_HAL_IMPL_RISCVV_INIT(int32x4, vint32, s32) +OPENCV_HAL_IMPL_RISCVV_INIT(uint64x2, vuint64, u64) +OPENCV_HAL_IMPL_RISCVV_INIT(int64x2, vint64, s64) +OPENCV_HAL_IMPL_RISCVV_INIT(float64x2, vfloat64, f64) +OPENCV_HAL_IMPL_RISCVV_INIT(float32x4, vfloat32, f32) +#define OPENCV_HAL_IMPL_RISCVV_INIT_SET(__Tp, _Tp, suffix, len, num) \ +inline v_##_Tp##x##num v_setzero_##suffix() { return v_##_Tp##x##num((v##_Tp##m1_t){0}); } \ +inline v_##_Tp##x##num v_setall_##suffix(__Tp v) { return v_##_Tp##x##num(vmv_v_x_##len##m1(v, num)); } + +OPENCV_HAL_IMPL_RISCVV_INIT_SET(uchar, uint8, u8, u8, 16) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(char, int8, s8, i8, 16) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(ushort, uint16, u16, u16, 8) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(short, int16, s16, i16, 8) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(unsigned int, uint32, u32, u32, 4) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(int, int32, s32, i32, 4) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(unsigned long, uint64, u64, u64, 2) +OPENCV_HAL_IMPL_RISCVV_INIT_SET(long, int64, s64, i64, 2) +inline v_float32x4 v_setzero_f32() { return v_float32x4((vfloat32m1_t){0}); } +inline v_float32x4 v_setall_f32(float v) { return v_float32x4(vfmv_v_f_f32m1(v, 4)); } + +inline v_float64x2 v_setzero_f64() { return v_float64x2(vfmv_v_f_f64m1(0, 2)); } +inline v_float64x2 v_setall_f64(double v) { return v_float64x2(vfmv_v_f_f64m1(v, 2)); } + + +#define OPENCV_HAL_IMPL_RISCVV_BIN_OP(bin_op, _Tpvec, intrin) \ +inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} \ +inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ +{ \ + a.val = intrin(a.val, b.val); \ + return a; \ +} + +#define OPENCV_HAL_IMPL_RISCVV_BIN_OPN(bin_op, _Tpvec, intrin, num) \ +inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val, num)); \ +} \ +inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ +{ \ + a.val = intrin(a.val, b.val, num); \ + return a; \ +} + +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_uint8x16, vsaddu_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_uint8x16, vssubu_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_int8x16, vsadd_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_int8x16, vssub_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_uint16x8, vsaddu_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_uint16x8, vssubu_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_int16x8, vsadd_vv_i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_int16x8, vssub_vv_i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_int32x4, vsadd_vv_i32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_int32x4, vssub_vv_i32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(*, v_int32x4, vmul_vv_i32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_uint32x4, vadd_vv_u32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_uint32x4, vsub_vv_u32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(*, v_uint32x4, vmul_vv_u32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_int64x2, vsadd_vv_i64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_int64x2, vssub_vv_i64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_uint64x2, vadd_vv_u64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_uint64x2, vsub_vv_u64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_float32x4, vfadd_vv_f32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_float32x4, vfsub_vv_f32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(*, v_float32x4, vfmul_vv_f32m1, 4) +inline v_float32x4 operator / (const v_float32x4& a, const v_float32x4& b) +{ + return v_float32x4(vfdiv_vv_f32m1(a.val, b.val, 4)); +} +inline v_float32x4& operator /= (v_float32x4& a, const v_float32x4& b) +{ + a.val = vfdiv_vv_f32m1(a.val, b.val, 4); + return a; +} + +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(+, v_float64x2, vfadd_vv_f64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(-, v_float64x2, vfsub_vv_f64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BIN_OPN(*, v_float64x2, vfmul_vv_f64m1, 2) +inline v_float64x2 operator / (const v_float64x2& a, const v_float64x2& b) +{ + return v_float64x2(vfdiv_vv_f64m1(a.val, b.val, 2)); +} +inline v_float64x2& operator /= (v_float64x2& a, const v_float64x2& b) +{ + a.val = vfdiv_vv_f64m1(a.val, b.val, 2); + return a; +} +// TODO: exp, log, sin, cos + +#define OPENCV_HAL_IMPL_RISCVV_BIN_FUNC(_Tpvec, func, intrin) \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} + +#define OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(_Tpvec, func, intrin, num) \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val, num)); \ +} +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint8x16, v_min, vminu_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint8x16, v_max, vmaxu_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int8x16, v_min, vmin_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int8x16, v_max, vmax_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint16x8, v_min, vminu_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint16x8, v_max, vmaxu_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int16x8, v_min, vmin_vv_i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int16x8, v_max, vmax_vv_i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint32x4, v_min, vminu_vv_u32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint32x4, v_max, vmaxu_vv_u32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int32x4, v_min, vmin_vv_i32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int32x4, v_max, vmax_vv_i32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_float32x4, v_min, vfmin_vv_f32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_float32x4, v_max, vfmax_vv_f32m1, 4) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_float64x2, v_min, vfmin_vv_f64m1, 2) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_float64x2, v_max, vfmax_vv_f64m1, 2) + +inline v_float32x4 v_sqrt(const v_float32x4& x) +{ + return v_float32x4(vfsqrt_v_f32m1(x.val, 4)); +} + +inline v_float32x4 v_invsqrt(const v_float32x4& x) +{ + return v_float32x4(vfrdiv_vf_f32m1(vfsqrt_v_f32m1(x.val, 4), 1, 4)); +} + +inline v_float32x4 v_magnitude(const v_float32x4& a, const v_float32x4& b) +{ + v_float32x4 x(vfmacc_vv_f32m1(vfmul_vv_f32m1(a.val, a.val, 4), b.val, b.val, 4)); + return v_sqrt(x); +} + +inline v_float32x4 v_sqr_magnitude(const v_float32x4& a, const v_float32x4& b) +{ + return v_float32x4(vfmacc_vv_f32m1(vfmul_vv_f32m1(a.val, a.val, 4), b.val, b.val, 4)); +} + +inline v_float32x4 v_fma(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) +{ + return v_float32x4(vfmacc_vv_f32m1(c.val, a.val, b.val, 4)); +} + +inline v_int32x4 v_fma(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ + return v_int32x4(vmacc_vv_i32m1(c.val, a.val, b.val, 4)); +} + +inline v_float32x4 v_muladd(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) +{ + return v_fma(a, b, c); +} + +inline v_int32x4 v_muladd(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ + return v_fma(a, b, c); +} + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + vfloat32m1_t res = vfmul_vf_f32m1(m0.val, v.val[0], 4);//vmuli_f32(m0.val, v.val, 0); + res = vfmacc_vf_f32m1(res, v.val[1], m1.val, 4);//vmulai_f32(res, m1.val, v.val, 1); + res = vfmacc_vf_f32m1(res, v.val[2], m2.val, 4);//vmulai_f32(res, m1.val, v.val, 1); + res = vfmacc_vf_f32m1(res, v.val[3], m3.val, 4);//vmulai_f32(res, m1.val, v.val, 1); + return v_float32x4(res); +} + +inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& a) +{ + vfloat32m1_t res = vfmul_vf_f32m1(m0.val, v.val[0], 4);//vmuli_f32(m0.val, v.val, 0); + res = vfmacc_vf_f32m1(res, v.val[1], m1.val, 4);//vmulai_f32(res, m1.val, v.val, 1); + res = vfmacc_vf_f32m1(res, v.val[2], m2.val, 4);//vmulai_f32(res, m1.val, v.val, 1); + res = vfadd_vv_f32m1(res, a.val, 4);//vmulai_f32(res, m1.val, v.val, 1); + return v_float32x4(res); +} + +inline v_float64x2 v_sqrt(const v_float64x2& x) +{ + return v_float64x2(vfsqrt_v_f64m1(x.val, 2)); +} + +inline v_float64x2 v_invsqrt(const v_float64x2& x) +{ + return v_float64x2(vfrdiv_vf_f64m1(vfsqrt_v_f64m1(x.val, 2), 1, 2)); +} + +inline v_float64x2 v_magnitude(const v_float64x2& a, const v_float64x2& b) +{ + v_float64x2 x(vfmacc_vv_f64m1(vfmul_vv_f64m1(a.val, a.val, 2), b.val, b.val, 2)); + return v_sqrt(x); +} + +inline v_float64x2 v_sqr_magnitude(const v_float64x2& a, const v_float64x2& b) +{ + return v_float64x2(vfmacc_vv_f64m1(vfmul_vv_f64m1(a.val, a.val, 2), b.val, b.val, 2)); +} + +inline v_float64x2 v_fma(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) +{ + return v_float64x2(vfmacc_vv_f64m1(c.val, a.val, b.val, 2)); +} + +inline v_float64x2 v_muladd(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) +{ + return v_fma(a, b, c); +} + +#define OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(_Tpvec, suffix, num) \ + OPENCV_HAL_IMPL_RISCVV_BIN_OPN(&, _Tpvec, vand_vv_##suffix, num) \ + OPENCV_HAL_IMPL_RISCVV_BIN_OPN(|, _Tpvec, vor_vv_##suffix, num) \ + OPENCV_HAL_IMPL_RISCVV_BIN_OPN(^, _Tpvec, vxor_vv_##suffix, num) \ + inline _Tpvec operator ~ (const _Tpvec & a) \ + { \ + return _Tpvec(vnot_v_##suffix(a.val, num)); \ + } + +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_uint8x16, u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_uint16x8, u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_uint32x4, u32m1, 4) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_uint64x2, u64m1, 2) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_int8x16, i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_int16x8, i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_int32x4, i32m1, 4) +OPENCV_HAL_IMPL_RISCVV_LOGIC_OPN(v_int64x2, i64m1, 2) + +#define OPENCV_HAL_IMPL_RISCVV_FLT_BIT_OP(bin_op, intrin) \ +inline v_float32x4 operator bin_op (const v_float32x4& a, const v_float32x4& b) \ +{ \ + return v_float32x4(vfloat32m1_t(intrin(vint32m1_t(a.val), vint32m1_t(b.val), 4))); \ +} \ +inline v_float32x4& operator bin_op##= (v_float32x4& a, const v_float32x4& b) \ +{ \ + a.val = vfloat32m1_t(intrin(vint32m1_t(a.val), vint32m1_t(b.val), 4)); \ + return a; \ +} + +OPENCV_HAL_IMPL_RISCVV_FLT_BIT_OP(&, vand_vv_i32m1) +OPENCV_HAL_IMPL_RISCVV_FLT_BIT_OP(|, vor_vv_i32m1) +OPENCV_HAL_IMPL_RISCVV_FLT_BIT_OP(^, vxor_vv_i32m1) + +inline v_float32x4 operator ~ (const v_float32x4& a) +{ + return v_float32x4((vfloat32m1_t)(vnot_v_i32m1((vint32m1_t)(a.val), 4))); +} + +#define OPENCV_HAL_IMPL_RISCVV_FLT_64BIT_OP(bin_op, intrin) \ +inline v_float64x2 operator bin_op (const v_float64x2& a, const v_float64x2& b) \ +{ \ + return v_float64x2(vfloat64m1_t(intrin(vint64m1_t(a.val), vint64m1_t(b.val), 2))); \ +} \ +inline v_float64x2& operator bin_op##= (v_float64x2& a, const v_float64x2& b) \ +{ \ + a.val = vfloat64m1_t(intrin(vint64m1_t(a.val), vint64m1_t(b.val), 2)); \ + return a; \ +} + +OPENCV_HAL_IMPL_RISCVV_FLT_64BIT_OP(&, vand_vv_i64m1) +OPENCV_HAL_IMPL_RISCVV_FLT_64BIT_OP(|, vor_vv_i64m1) +OPENCV_HAL_IMPL_RISCVV_FLT_64BIT_OP(^, vxor_vv_i64m1) + +inline v_float64x2 operator ~ (const v_float64x2& a) +{ + return v_float64x2((vfloat64m1_t)(vnot_v_i64m1((vint64m1_t)(a.val), 2))); +} +inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b) +{ + return v_int16x8(vmulh_vv_i16m1(a.val, b.val, 8)); +} +inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b) +{ + return v_uint16x8(vmulhu_vv_u16m1(a.val, b.val, 8)); +} + +//#define OPENCV_HAL_IMPL_RISCVV_ABS(_Tpuvec, _Tpsvec, usuffix, ssuffix) \ +//inline _Tpuvec v_abs(const _Tpsvec& a) { \ +// E##xm1_t mask=vmflt_vf_e32xm1_f32m1(x.val, 0.0, 4); + +//OPENCV_HAL_IMPL_RISCVV_ABS(v_uint8x16, v_int8x16, u8, s8) +//OPENCV_HAL_IMPL_RISCVV_ABS(v_uint16x8, v_int16x8, u16, s16) +//OPENCV_HAL_IMPL_RISCVV_ABS(v_uint32x4, v_int32x4, u32, s32) + +inline v_uint32x4 v_abs(v_int32x4 x) +{ + vbool32_t mask=vmslt_vx_i32m1_b32(x.val, 0, 4); + return v_uint32x4((vuint32m1_t)vrsub_vx_i32m1_m(mask, x.val, x.val, 0, 4)); +} + +inline v_uint16x8 v_abs(v_int16x8 x) +{ + vbool16_t mask=vmslt_vx_i16m1_b16(x.val, 0, 8); + return v_uint16x8((vuint16m1_t)vrsub_vx_i16m1_m(mask, x.val, x.val, 0, 8)); +} + +inline v_uint8x16 v_abs(v_int8x16 x) +{ + vbool8_t mask=vmslt_vx_i8m1_b8(x.val, 0, 16); + return v_uint8x16((vuint8m1_t)vrsub_vx_i8m1_m(mask, x.val, x.val, 0, 16)); +} + +inline v_float32x4 v_abs(v_float32x4 x) +{ + return (v_float32x4)vfsgnjx_vv_f32m1(x.val, x.val, 4); +} + +inline v_float64x2 v_abs(v_float64x2 x) +{ + return (v_float64x2)vfsgnjx_vv_f64m1(x.val, x.val, 2); +} + +inline v_float32x4 v_absdiff(const v_float32x4& a, const v_float32x4& b) +{ + vfloat32m1_t ret = vfsub_vv_f32m1(a.val, b.val, 4); + return (v_float32x4)vfsgnjx_vv_f32m1(ret, ret, 4); +} + +inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b) +{ + vfloat64m1_t ret = vfsub_vv_f64m1(a.val, b.val, 2); + return (v_float64x2)vfsgnjx_vv_f64m1(ret, ret, 2); +} + +#define OPENCV_HAL_IMPL_RISCVV_ABSDIFF_U(bit, num) \ +inline v_uint##bit##x##num v_absdiff(v_uint##bit##x##num a, v_uint##bit##x##num b){ \ + vuint##bit##m1_t vmax = vmaxu_vv_u##bit##m1(a.val, b.val, num); \ + vuint##bit##m1_t vmin = vminu_vv_u##bit##m1(a.val, b.val, num); \ + return v_uint##bit##x##num(vsub_vv_u##bit##m1(vmax, vmin, num));\ +} + +OPENCV_HAL_IMPL_RISCVV_ABSDIFF_U(8, 16) +OPENCV_HAL_IMPL_RISCVV_ABSDIFF_U(16, 8) +OPENCV_HAL_IMPL_RISCVV_ABSDIFF_U(32, 4) + +/** Saturating absolute difference **/ +inline v_int8x16 v_absdiffs(v_int8x16 a, v_int8x16 b){ + vint8m1_t vmax = vmax_vv_i8m1(a.val, b.val, 16); + vint8m1_t vmin = vmin_vv_i8m1(a.val, b.val, 16); + return v_int8x16(vssub_vv_i8m1(vmax, vmin, 16)); +} +inline v_int16x8 v_absdiffs(v_int16x8 a, v_int16x8 b){ + vint16m1_t vmax = vmax_vv_i16m1(a.val, b.val, 8); + vint16m1_t vmin = vmin_vv_i16m1(a.val, b.val, 8); + return v_int16x8(vssub_vv_i16m1(vmax, vmin, 8)); +} + +#define OPENCV_HAL_IMPL_RISCVV_ABSDIFF(_Tpvec, _Tpv, num) \ +inline v_uint##_Tpvec v_absdiff(v_int##_Tpvec a, v_int##_Tpvec b){ \ + vint##_Tpv##_t max = vmax_vv_i##_Tpv(a.val, b.val, num);\ + vint##_Tpv##_t min = vmin_vv_i##_Tpv(a.val, b.val, num);\ + return v_uint##_Tpvec((vuint##_Tpv##_t)vsub_vv_i##_Tpv(max, min, num)); \ +} + +OPENCV_HAL_IMPL_RISCVV_ABSDIFF(8x16, 8m1, 16) +OPENCV_HAL_IMPL_RISCVV_ABSDIFF(16x8, 16m1, 8) +OPENCV_HAL_IMPL_RISCVV_ABSDIFF(32x4, 32m1, 4) + +// Multiply and expand +inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b, + v_int16x8& c, v_int16x8& d) +{ + vint16m2_t res = vundefined_i16m2(); + res = vwmul_vv_i16m2(a.val, b.val, 16); + c.val = vget_i16m2_i16m1(res, 0); + d.val = vget_i16m2_i16m1(res, 1); +} + +inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b, + v_uint16x8& c, v_uint16x8& d) +{ + vuint16m2_t res = vundefined_u16m2(); + res = vwmulu_vv_u16m2(a.val, b.val, 16); + c.val = vget_u16m2_u16m1(res, 0); + d.val = vget_u16m2_u16m1(res, 1); +} + +inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b, + v_int32x4& c, v_int32x4& d) +{ + vint32m2_t res = vundefined_i32m2(); + res = vwmul_vv_i32m2(a.val, b.val, 8); + c.val = vget_i32m2_i32m1(res, 0); + d.val = vget_i32m2_i32m1(res, 1); +} + +inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b, + v_uint32x4& c, v_uint32x4& d) +{ + vuint32m2_t res = vundefined_u32m2(); + res = vwmulu_vv_u32m2(a.val, b.val, 8); + c.val = vget_u32m2_u32m1(res, 0); + d.val = vget_u32m2_u32m1(res, 1); +} + +inline void v_mul_expand(const v_int32x4& a, const v_int32x4& b, + v_int64x2& c, v_int64x2& d) +{ + vint64m2_t res = vundefined_i64m2(); + res = vwmul_vv_i64m2(a.val, b.val, 4); + c.val = vget_i64m2_i64m1(res, 0); + d.val = vget_i64m2_i64m1(res, 1); +} + +inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, + v_uint64x2& c, v_uint64x2& d) +{ + vuint64m2_t res = vundefined_u64m2(); + res = vwmulu_vv_u64m2(a.val, b.val, 4); + c.val = vget_u64m2_u64m1(res, 0); + d.val = vget_u64m2_u64m1(res, 1); +} + +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint8x16, v_add_wrap, vadd_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int8x16, v_add_wrap, vadd_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint16x8, v_add_wrap, vadd_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int16x8, v_add_wrap, vadd_vv_i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint8x16, v_sub_wrap, vsub_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int8x16, v_sub_wrap, vsub_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint16x8, v_sub_wrap, vsub_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int16x8, v_sub_wrap, vsub_vv_i16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint8x16, v_mul_wrap, vmul_vv_u8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int8x16, v_mul_wrap, vmul_vv_i8m1, 16) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_uint16x8, v_mul_wrap, vmul_vv_u16m1, 8) +OPENCV_HAL_IMPL_RISCVV_BINN_FUNC(v_int16x8, v_mul_wrap, vmul_vv_i16m1, 8) +//////// Dot Product //////// +// 16 >> 32 +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b) +{ + vint32m2_t res = vundefined_i32m2(); + res = vwmul_vv_i32m2(a.val, b.val, 8); + res = vrgather_vv_i32m2(res, (vuint32m2_t){0, 2, 4, 6, 1, 3, 5, 7}, 8); + return v_int32x4(vadd_vv_i32m1(vget_i32m2_i32m1(res, 0), vget_i32m2_i32m1(res, 1), 4)); +} +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c) +{ + vint32m2_t res = vundefined_i32m2(); + res = vwmul_vv_i32m2(a.val, b.val, 8); + res = vrgather_vv_i32m2(res, (vuint32m2_t){0, 2, 4, 6, 1, 3, 5, 7}, 8); + return v_int32x4(vadd_vv_i32m1(vadd_vv_i32m1(vget_i32m2_i32m1(res, 0),vget_i32m2_i32m1(res, 1), 4), c.val, 4)); +} + +// 32 >> 64 +inline v_int64x2 v_dotprod(const v_int32x4& a, const v_int32x4& b) +{ + vint64m2_t res = vundefined_i64m2(); + res = vwmul_vv_i64m2(a.val, b.val, 4); + res = vrgather_vv_i64m2(res, (vuint64m2_t){0, 2, 1, 3}, 4); + return v_int64x2(vadd_vv_i64m1(vget_i64m2_i64m1(res, 0), vget_i64m2_i64m1(res, 1), 2)); +} +inline v_int64x2 v_dotprod(const v_int32x4& a, const v_int32x4& b, const v_int64x2& c) +{ + vint64m2_t res = vundefined_i64m2(); + res = vwmul_vv_i64m2(a.val, b.val, 4); + res = vrgather_vv_i64m2(res, (vuint64m2_t){0, 2, 1, 3}, 4); + return v_int64x2(vadd_vv_i64m1(vadd_vv_i64m1(vget_i64m2_i64m1(res, 0), vget_i64m2_i64m1(res, 1), 2), c.val, 2)); +} + +// 8 >> 32 +inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b) +{ + vuint16m2_t v1 = vundefined_u16m2(); + vuint32m2_t v2 = vundefined_u32m2(); + v1 = vwmulu_vv_u16m2(a.val, b.val, 16); + v1 = vrgather_vv_u16m2(v1, (vuint16m2_t){0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}, 16); + v2 = vwaddu_vv_u32m2(vget_u16m2_u16m1(v1, 0), vget_u16m2_u16m1(v1, 1), 8); + return v_uint32x4(vadd_vv_u32m1(vget_u32m2_u32m1(v2, 0), vget_u32m2_u32m1(v2, 1), 4)); +} + +inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b, + const v_uint32x4& c) +{ + vuint16m2_t v1 = vundefined_u16m2(); + vuint32m2_t v2 = vundefined_u32m2(); + v1 = vwmulu_vv_u16m2(a.val, b.val, 16); + v1 = vrgather_vv_u16m2(v1, (vuint16m2_t){0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}, 16); + v2 = vwaddu_vv_u32m2(vget_u16m2_u16m1(v1, 0), vget_u16m2_u16m1(v1, 1), 8); + return v_uint32x4(vadd_vv_u32m1(vadd_vv_u32m1(vget_u32m2_u32m1(v2, 0), vget_u32m2_u32m1(v2, 1), 4), c.val, 4)); +} + +inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b) +{ + vint16m2_t v1 = vundefined_i16m2(); + vint32m2_t v2 = vundefined_i32m2(); + v1 = vwmul_vv_i16m2(a.val, b.val, 16); + v1 = vrgather_vv_i16m2(v1, (vuint16m2_t){0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}, 16); + v2 = vwadd_vv_i32m2(vget_i16m2_i16m1(v1, 0), vget_i16m2_i16m1(v1, 1), 8); + return v_int32x4(vadd_vv_i32m1(vget_i32m2_i32m1(v2, 0), vget_i32m2_i32m1(v2, 1), 4)); +} + +inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b, + const v_int32x4& c) +{ + vint16m2_t v1 = vundefined_i16m2(); + vint32m2_t v2 = vundefined_i32m2(); + v1 = vwmul_vv_i16m2(a.val, b.val, 16); + v1 = vrgather_vv_i16m2(v1, (vuint16m2_t){0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}, 16); + v2 = vwadd_vv_i32m2(vget_i16m2_i16m1(v1, 0), vget_i16m2_i16m1(v1, 1), 8); + return v_int32x4(vadd_vv_i32m1(vadd_vv_i32m1(vget_i32m2_i32m1(v2, 0), vget_i32m2_i32m1(v2, 1), 4), c.val, 4)); +} + +inline v_uint64x2 v_dotprod_expand(const v_uint16x8& a, const v_uint16x8& b) +{ + vuint32m2_t v1 = vundefined_u32m2(); + vuint64m2_t v2 = vundefined_u64m2(); + v1 = vwmulu_vv_u32m2(a.val, b.val, 8); + v1 = vrgather_vv_u32m2(v1, (vuint32m2_t){0, 4, 1, 5, 2, 6, 3, 7}, 8); + v2 = vwaddu_vv_u64m2(vget_u32m2_u32m1(v1, 0), vget_u32m2_u32m1(v1, 1), 4); + return v_uint64x2(vadd_vv_u64m1(vget_u64m2_u64m1(v2, 0), vget_u64m2_u64m1(v2, 1), 2)); +} + +inline v_uint64x2 v_dotprod_expand(const v_uint16x8& a, const v_uint16x8& b, + const v_uint64x2& c) +{ + vuint32m2_t v1 = vundefined_u32m2(); + vuint64m2_t v2 = vundefined_u64m2(); + v1 = vwmulu_vv_u32m2(a.val, b.val, 8); + v1 = vrgather_vv_u32m2(v1, (vuint32m2_t){0, 4, 1, 5, 2, 6, 3, 7}, 8); + v2 = vwaddu_vv_u64m2(vget_u32m2_u32m1(v1, 0), vget_u32m2_u32m1(v1, 1), 4); + return v_uint64x2(vadd_vv_u64m1(vadd_vv_u64m1(vget_u64m2_u64m1(v2, 0), vget_u64m2_u64m1(v2, 1), 2), c.val, 2)); +} + +inline v_int64x2 v_dotprod_expand(const v_int16x8& a, const v_int16x8& b) +{ + vint32m2_t v1 = vundefined_i32m2(); + vint64m2_t v2 = vundefined_i64m2(); + v1 = vwmul_vv_i32m2(a.val, b.val, 8); + v1 = vrgather_vv_i32m2(v1, (vuint32m2_t){0, 4, 1, 5, 2, 6, 3, 7}, 8); + v2 = vwadd_vv_i64m2(vget_i32m2_i32m1(v1, 0), vget_i32m2_i32m1(v1, 1), 4); + return v_int64x2(vadd_vv_i64m1(vget_i64m2_i64m1(v2, 0), vget_i64m2_i64m1(v2, 1), 2)); +} + +inline v_int64x2 v_dotprod_expand(const v_int16x8& a, const v_int16x8& b, + const v_int64x2& c) +{ + vint32m2_t v1 = vundefined_i32m2(); + vint64m2_t v2 = vundefined_i64m2(); + v1 = vwmul_vv_i32m2(a.val, b.val, 8); + v1 = vrgather_vv_i32m2(v1, (vuint32m2_t){0, 4, 1, 5, 2, 6, 3, 7}, 8); + v2 = vwadd_vv_i64m2(vget_i32m2_i32m1(v1, 0), vget_i32m2_i32m1(v1, 1), 4); + return v_int64x2(vadd_vv_i64m1(vadd_vv_i64m1(vget_i64m2_i64m1(v2, 0), vget_i64m2_i64m1(v2, 1), 2), c.val, 2)); +} + +//////// Fast Dot Product //////// +// 16 >> 32 +inline v_int32x4 v_dotprod_fast(const v_int16x8& a, const v_int16x8& b) +{ + vint32m2_t v1 = vundefined_i32m2(); + v1 = vwmul_vv_i32m2(a.val, b.val, 8); + return v_int32x4(vadd_vv_i32m1(vget_i32m2_i32m1(v1, 0), vget_i32m2_i32m1(v1, 1), 4)); +} + +inline v_int32x4 v_dotprod_fast(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c) +{ + vint32m2_t v1 = vundefined_i32m2(); + v1 = vwmul_vv_i32m2(a.val, b.val, 8); + return v_int32x4(vadd_vv_i32m1(vadd_vv_i32m1(vget_i32m2_i32m1(v1, 0), vget_i32m2_i32m1(v1, 1), 4), c.val, 4)); +} + +// 32 >> 64 +inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b) +{ + vint64m2_t v1 = vundefined_i64m2(); + v1 = vwmul_vv_i64m2(a.val, b.val, 4); + return v_int64x2(vadd_vv_i64m1(vget_i64m2_i64m1(v1, 0), vget_i64m2_i64m1(v1, 1), 2)); +} +inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b, const v_int64x2& c) +{ + vint64m2_t v1 = vundefined_i64m2(); + v1 = vwmul_vv_i64m2(a.val, b.val, 8); + return v_int64x2(vadd_vv_i64m1(vadd_vv_i64m1(vget_i64m2_i64m1(v1, 0), vget_i64m2_i64m1(v1, 1), 4), c.val, 4)); +} + +// 8 >> 32 +inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b) +{ + vuint16m2_t v1 = vundefined_u16m2(); + vuint32m2_t v2 = vundefined_u32m2(); + v1 = vwmulu_vv_u16m2(a.val, b.val, 16); + v2 = vwaddu_vv_u32m2(vget_u16m2_u16m1(v1, 0), vget_u16m2_u16m1(v1, 1), 8); + return v_uint32x4(vadd_vv_u32m1(vget_u32m2_u32m1(v2, 0), vget_u32m2_u32m1(v2, 1), 4)); +} + +inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b, const v_uint32x4& c) +{ + vuint16m2_t v1 = vundefined_u16m2(); + vuint32m2_t v2 = vundefined_u32m2(); + v1 = vwmulu_vv_u16m2(a.val, b.val, 16); + v2 = vwaddu_vv_u32m2(vget_u16m2_u16m1(v1, 0), vget_u16m2_u16m1(v1, 1), 8); + return v_uint32x4(vadd_vv_u32m1(vadd_vv_u32m1(vget_u32m2_u32m1(v2, 0), vget_u32m2_u32m1(v2, 1), 4), c.val, 4)); +} + +inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b) +{ + vint16m2_t v1 = vundefined_i16m2(); + vint32m2_t v2 = vundefined_i32m2(); + v1 = vwmul_vv_i16m2(a.val, b.val, 16); + v2 = vwadd_vv_i32m2(vget_i16m2_i16m1(v1, 0), vget_i16m2_i16m1(v1, 1), 8); + return v_int32x4(vadd_vv_i32m1(vget_i32m2_i32m1(v2, 0), vget_i32m2_i32m1(v2, 1), 4)); +} +inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b, const v_int32x4& c) +{ + vint16m2_t v1 = vundefined_i16m2(); + vint32m2_t v2 = vundefined_i32m2(); + v1 = vwmul_vv_i16m2(a.val, b.val, 16); + v2 = vwadd_vv_i32m2(vget_i16m2_i16m1(v1, 0), vget_i16m2_i16m1(v1, 1), 8); + return v_int32x4(vadd_vv_i32m1(vadd_vv_i32m1(vget_i32m2_i32m1(v2, 0), vget_i32m2_i32m1(v2, 1), 4), c.val, 4)); +} + +// 16 >> 64 +inline v_uint64x2 v_dotprod_expand_fast(const v_uint16x8& a, const v_uint16x8& b) +{ + vuint32m2_t v1 = vundefined_u32m2(); + vuint64m2_t v2 = vundefined_u64m2(); + v1 = vwmulu_vv_u32m2(a.val, b.val, 8); + v2 = vwaddu_vv_u64m2(vget_u32m2_u32m1(v1, 0), vget_u32m2_u32m1(v1, 1), 4); + return v_uint64x2(vadd_vv_u64m1(vget_u64m2_u64m1(v2, 0), vget_u64m2_u64m1(v2, 1), 2)); +} +inline v_uint64x2 v_dotprod_expand_fast(const v_uint16x8& a, const v_uint16x8& b, const v_uint64x2& c) +{ + vuint32m2_t v1 = vundefined_u32m2(); + vuint64m2_t v2 = vundefined_u64m2(); + v1 = vwmulu_vv_u32m2(a.val, b.val, 8); + v2 = vwaddu_vv_u64m2(vget_u32m2_u32m1(v1, 0), vget_u32m2_u32m1(v1, 1), 4); + return v_uint64x2(vadd_vv_u64m1(vadd_vv_u64m1(vget_u64m2_u64m1(v2, 0), vget_u64m2_u64m1(v2, 1), 2), c.val, 2)); +} + +inline v_int64x2 v_dotprod_expand_fast(const v_int16x8& a, const v_int16x8& b) +{ + vint32m2_t v1 = vundefined_i32m2(); + vint64m2_t v2 = vundefined_i64m2(); + v1 = vwmul_vv_i32m2(a.val, b.val, 8); + v2 = vwadd_vv_i64m2(vget_i32m2_i32m1(v1, 0), vget_i32m2_i32m1(v1, 1), 4); + return v_int64x2(vadd_vv_i64m1(vget_i64m2_i64m1(v2, 0), vget_i64m2_i64m1(v2, 1), 2)); +} +inline v_int64x2 v_dotprod_expand_fast(const v_int16x8& a, const v_int16x8& b, const v_int64x2& c) +{ + vint32m2_t v1 = vundefined_i32m2(); + vint64m2_t v2 = vundefined_i64m2(); + v1 = vwmul_vv_i32m2(a.val, b.val, 8); + v2 = vwadd_vv_i64m2(vget_i32m2_i32m1(v1, 0), vget_i32m2_i32m1(v1, 1), 4); + return v_int64x2(vadd_vv_i64m1(vadd_vv_i64m1(vget_i64m2_i64m1(v2, 0), vget_i64m2_i64m1(v2, 1), 2), c.val, 2)); +} + + +#define OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(_Tpvec, _Tpvec2, len, scalartype, func, intrin, num) \ +inline scalartype v_reduce_##func(const v_##_Tpvec##x##num& a) \ +{\ + v##_Tpvec2##m1_t val = vmv_v_x_##len##m1(0, num); \ + val = intrin(val, a.val, val, num); \ + return vmv_x_s_##len##m1_##len(val, num); \ +} + + +#define OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(_Tpvec, _Tpvec2, scalartype, func, funcu, num) \ +inline scalartype v_reduce_##func(const v_##_Tpvec##x##num& a) \ +{\ + v##_Tpvec##m1_t val = (v##_Tpvec##m1_t)vmv_v_x_i8m1(0, num); \ + val = v##funcu##_vs_##_Tpvec2##m1_##_Tpvec2##m1(val, a.val, a.val, num); \ + return val[0]; \ +} +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(int8, int16, i16, int, sum, vwredsum_vs_i8m1_i16m1, 16) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(int16, int32, i32, int, sum, vwredsum_vs_i16m1_i32m1, 8) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(int32, int64, i64, int, sum, vwredsum_vs_i32m1_i64m1, 4) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(uint8, uint16, u16, unsigned, sum, vwredsumu_vs_u8m1_u16m1, 16) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(uint16, uint32, u32, unsigned, sum, vwredsumu_vs_u16m1_u32m1, 8) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_W(uint32, uint64, u64, unsigned, sum, vwredsumu_vs_u32m1_u64m1, 4) +inline float v_reduce_sum(const v_float32x4& a) \ +{\ + vfloat32m1_t val = vfmv_v_f_f32m1(0.0, 4); \ + val = vfredsum_vs_f32m1_f32m1(val, a.val, val, 4); \ + return vfmv_f_s_f32m1_f32(val, 4); \ +} +inline double v_reduce_sum(const v_float64x2& a) \ +{\ + vfloat64m1_t val = vfmv_v_f_f64m1(0.0, 2); \ + val = vfredsum_vs_f64m1_f64m1(val, a.val, val, 2); \ + return vfmv_f_s_f64m1_f64(val, 2); \ +} +inline uint64 v_reduce_sum(const v_uint64x2& a) +{ return vext_x_v_u64m1_u64((vuint64m1_t)a.val, 0, 2)+vext_x_v_u64m1_u64((vuint64m1_t)a.val, 1, 2); } + +inline int64 v_reduce_sum(const v_int64x2& a) +{ return vext_x_v_i64m1_i64((vint64m1_t)a.val, 0, 2)+vext_x_v_i64m1_i64((vint64m1_t)a.val, 1, 2); } + +#define OPENCV_HAL_IMPL_RISCVV_REDUCE_OP(func) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(int8, i8, int, func, red##func, 16) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(int16, i16, int, func, red##func, 8) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(int32, i32, int, func, red##func, 4) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(int64, i64, int, func, red##func, 2) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(uint8, u8, unsigned, func, red##func##u, 16) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(uint16, u16, unsigned, func, red##func##u, 8) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(uint32, u32, unsigned, func, red##func##u, 4) \ +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP_(float32, f32, float, func, fred##func, 4) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP(max) +OPENCV_HAL_IMPL_RISCVV_REDUCE_OP(min) + +inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, const v_float32x4& d) +{ + vfloat32m1_t a0 = vfmv_v_f_f32m1(0.0, 4); + vfloat32m1_t b0 = vfmv_v_f_f32m1(0.0, 4); + vfloat32m1_t c0 = vfmv_v_f_f32m1(0.0, 4); + vfloat32m1_t d0 = vfmv_v_f_f32m1(0.0, 4); + a0 = vfredsum_vs_f32m1_f32m1(a0, a.val, a0, 4); + b0 = vfredsum_vs_f32m1_f32m1(b0, b.val, b0, 4); + c0 = vfredsum_vs_f32m1_f32m1(c0, c.val, c0, 4); + d0 = vfredsum_vs_f32m1_f32m1(d0, d.val, d0, 4); + return v_float32x4(a0[0], b0[0], c0[0], d0[0]); +} + +inline float v_reduce_sad(const v_float32x4& a, const v_float32x4& b) +{ + vfloat32m1_t a0 = vfmv_v_f_f32m1(0.0, 4); + vfloat32m1_t x = vfsub_vv_f32m1(a.val, b.val, 4); + vbool32_t mask=vmflt_vf_f32m1_b32(x, 0, 4); + vfloat32m1_t val = vfrsub_vf_f32m1_m(mask, x, x, 0, 4); + a0 = vfredsum_vs_f32m1_f32m1(a0, val, a0, 4); + return a0[0]; +} + +#define OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(_Tpvec, _Tpvec2) \ +inline unsigned v_reduce_sad(const _Tpvec& a, const _Tpvec&b){ \ + _Tpvec2 x = v_absdiff(a, b); \ + return v_reduce_sum(x); \ +} + +OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(v_int8x16, v_uint8x16) +OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(v_uint8x16, v_uint8x16) +OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(v_int16x8, v_uint16x8) +OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(v_uint16x8, v_uint16x8) +OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(v_int32x4, v_uint32x4) +OPENCV_HAL_IMPL_RISCVV_REDUCE_SAD(v_uint32x4, v_uint32x4) + +#define OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(_Tpvec, _Tp, _T, num, uv) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ \ + vbool##_T##_t mask = vmseq_vv_##_Tp##_b##_T(a.val, b.val, num); \ + return _Tpvec(vmerge_vxm_##_Tp(mask, vmv_v_x_##_Tp(0, num), -1, num)); \ +} \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ \ + vbool##_T##_t mask = vmsne_vv_##_Tp##_b##_T(a.val, b.val, num); \ + return _Tpvec(vmerge_vxm_##_Tp(mask, vmv_v_x_##_Tp(0, num), -1, num)); \ +} \ +inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ +{ \ + vbool##_T##_t mask = vmslt##uv##_Tp##_b##_T(a.val, b.val, num); \ + return _Tpvec(vmerge_vxm_##_Tp(mask, vmv_v_x_##_Tp(0, num), -1, num)); \ +} \ +inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \ +{ \ + vbool##_T##_t mask = vmslt##uv##_Tp##_b##_T(b.val, a.val, num); \ + return _Tpvec(vmerge_vxm_##_Tp(mask, vmv_v_x_##_Tp(0, num), -1, num)); \ +} \ +inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ +{ \ + vbool##_T##_t mask = vmsle##uv##_Tp##_b##_T(a.val, b.val, num); \ + return _Tpvec(vmerge_vxm_##_Tp(mask, vmv_v_x_##_Tp(0, num), -1, num)); \ +} \ +inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ +{ \ + vbool##_T##_t mask = vmsle##uv##_Tp##_b##_T(b.val, a.val, num); \ + return _Tpvec(vmerge_vxm_##_Tp(mask, vmv_v_x_##_Tp(0, num), -1, num)); \ +} \ + +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_int8x16, i8m1, 8, 16, _vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_int16x8, i16m1, 16, 8, _vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_int32x4, i32m1, 32, 4, _vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_int64x2, i64m1, 64, 2, _vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_uint8x16, u8m1, 8, 16, u_vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_uint16x8, u16m1, 16, 8, u_vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_uint32x4, u32m1, 32, 4, u_vv_) +OPENCV_HAL_IMPL_RISCVV_INT_CMP_OP(v_uint64x2, u64m1, 64, 2, u_vv_) + +//TODO: == +inline v_float32x4 operator == (const v_float32x4& a, const v_float32x4& b) +{ + vbool32_t mask = vmfeq_vv_f32m1_b32(a.val, b.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} +inline v_float32x4 operator != (const v_float32x4& a, const v_float32x4& b) +{ + vbool32_t mask = vmfne_vv_f32m1_b32(a.val, b.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} +inline v_float32x4 operator < (const v_float32x4& a, const v_float32x4& b) +{ + vbool32_t mask = vmflt_vv_f32m1_b32(a.val, b.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} +inline v_float32x4 operator <= (const v_float32x4& a, const v_float32x4& b) +{ + vbool32_t mask = vmfle_vv_f32m1_b32(a.val, b.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} +inline v_float32x4 operator > (const v_float32x4& a, const v_float32x4& b) +{ + vbool32_t mask = vmfgt_vv_f32m1_b32(a.val, b.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} +inline v_float32x4 operator >= (const v_float32x4& a, const v_float32x4& b) +{ + vbool32_t mask = vmfge_vv_f32m1_b32(a.val, b.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} +inline v_float32x4 v_not_nan(const v_float32x4& a) +{ + vbool32_t mask = vmford_vv_f32m1_b32(a.val, a.val, 4); + vint32m1_t res = vmerge_vxm_i32m1(mask, vmv_v_x_i32m1(0.0, 4), -1, 4); + return v_float32x4((vfloat32m1_t)res); +} + +//TODO: == +inline v_float64x2 operator == (const v_float64x2& a, const v_float64x2& b) +{ + vbool64_t mask = vmfeq_vv_f64m1_b64(a.val, b.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +inline v_float64x2 operator != (const v_float64x2& a, const v_float64x2& b) +{ + vbool64_t mask = vmfne_vv_f64m1_b64(a.val, b.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +inline v_float64x2 operator < (const v_float64x2& a, const v_float64x2& b) +{ + vbool64_t mask = vmflt_vv_f64m1_b64(a.val, b.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +inline v_float64x2 operator <= (const v_float64x2& a, const v_float64x2& b) +{ + vbool64_t mask = vmfle_vv_f64m1_b64(a.val, b.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +inline v_float64x2 operator > (const v_float64x2& a, const v_float64x2& b) +{ + vbool64_t mask = vmfgt_vv_f64m1_b64(a.val, b.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +inline v_float64x2 operator >= (const v_float64x2& a, const v_float64x2& b) +{ + vbool64_t mask = vmfge_vv_f64m1_b64(a.val, b.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +inline v_float64x2 v_not_nan(const v_float64x2& a) +{ + vbool64_t mask = vmford_vv_f64m1_b64(a.val, a.val, 2); + vint64m1_t res = vmerge_vxm_i64m1(mask, vmv_v_x_i64m1(0.0, 2), -1, 2); + return v_float64x2((vfloat64m1_t)res); +} +#define OPENCV_HAL_IMPL_RISCVV_TRANSPOSE4x4(_Tp, _T) \ +inline void v_transpose4x4(const v_##_Tp##32x4& a0, const v_##_Tp##32x4& a1, \ + const v_##_Tp##32x4& a2, const v_##_Tp##32x4& a3, \ + v_##_Tp##32x4& b0, v_##_Tp##32x4& b1, \ + v_##_Tp##32x4& b2, v_##_Tp##32x4& b3) \ +{ \ + v##_Tp##32m4_t val = vundefined_##_T##m4(); \ + val = vset_##_T##m4(val, 0, a0.val); \ + val = vset_##_T##m4(val, 1, a1.val); \ + val = vset_##_T##m4(val, 2, a2.val); \ + val = vset_##_T##m4(val, 3, a3.val); \ + val = vrgather_vv_##_T##m4(val, (vuint32m4_t){0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}, 16); \ + b0.val = vget_##_T##m4_##_T##m1(val, 0); \ + b1.val = vget_##_T##m4_##_T##m1(val, 1); \ + b2.val = vget_##_T##m4_##_T##m1(val, 2); \ + b3.val = vget_##_T##m4_##_T##m1(val, 3); \ +} +OPENCV_HAL_IMPL_RISCVV_TRANSPOSE4x4(uint, u32) +OPENCV_HAL_IMPL_RISCVV_TRANSPOSE4x4(int, i32) +OPENCV_HAL_IMPL_RISCVV_TRANSPOSE4x4(float, f32) + + +#define OPENCV_HAL_IMPL_RISCVV_SHIFT_LEFT(_Tpvec, suffix, _T, num) \ +inline _Tpvec operator << (const _Tpvec& a, int n) \ +{ return _Tpvec((vsll_vx_##_T##m1(a.val, n, num))); } \ +template inline _Tpvec v_shl(const _Tpvec& a) \ +{ return _Tpvec((vsll_vx_##_T##m1(a.val, n, num))); } + +#define OPENCV_HAL_IMPL_RISCVV_SHIFT_RIGHT(_Tpvec, suffix, _T, num, intric) \ +inline _Tpvec operator >> (const _Tpvec& a, int n) \ +{ return _Tpvec((v##intric##_vx_##_T##m1(a.val, n, num))); } \ +template inline _Tpvec v_shr(const _Tpvec& a) \ +{ return _Tpvec((v##intric##_vx_##_T##m1(a.val, n, num))); }\ +template inline _Tpvec v_rshr(const _Tpvec& a) \ +{ return _Tpvec((v##intric##_vx_##_T##m1(vadd_vx_##_T##m1(a.val, 1<<(n-1), num), n, num))); } + +// trade efficiency for convenience +#define OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(suffix, _T, num, intrin) \ +OPENCV_HAL_IMPL_RISCVV_SHIFT_LEFT(v_##suffix##x##num, suffix, _T, num) \ +OPENCV_HAL_IMPL_RISCVV_SHIFT_RIGHT(v_##suffix##x##num, suffix, _T, num, intrin) + +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(uint8, u8, 16, srl) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(uint16, u16, 8, srl) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(uint32, u32, 4, srl) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(uint64, u64, 2, srl) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(int8, i8, 16, sra) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(int16, i16, 8, sra) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(int32, i32, 4, sra) +OPENCV_HAL_IMPL_RISCVV_SHIFT_OP(int64, i64, 2, sra) + +#if 0 +#define VUP4(n) {0, 1, 2, 3} +#define VUP8(n) {0, 1, 2, 3, 4, 5, 6, 7} +#define VUP16(n) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} +#define VUP2(n) {0, 1} +#endif +#define OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(_Tpvec, suffix, _T, num, num2, vmv, len) \ +template inline _Tpvec v_rotate_left(const _Tpvec& a) \ +{ \ + suffix##m1_t tmp = vmv##_##_T##m1(0, num);\ + tmp = vslideup_vx_##_T##m1_m(vmset_m_##len(num), tmp, a.val, n, num);\ + return _Tpvec(tmp);\ +} \ +template inline _Tpvec v_rotate_right(const _Tpvec& a) \ +{ \ + return _Tpvec(vslidedown_vx_##_T##m1(a.val, n, num));\ +} \ +template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a) \ +{ return a; } \ +template inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) \ +{ \ + suffix##m2_t tmp = vundefined_##_T##m2(); \ + tmp = vset_##_T##m2(tmp, 0, a.val); \ + tmp = vset_##_T##m2(tmp, 1, b.val); \ + tmp = vslidedown_vx_##_T##m2(tmp, n, num2);\ + return _Tpvec(vget_##_T##m2_##_T##m1(tmp, 0));\ +} \ +template inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) \ +{ \ + suffix##m2_t tmp = vundefined_##_T##m2(); \ + tmp = vset_##_T##m2(tmp, 0, b.val); \ + tmp = vset_##_T##m2(tmp, 1, a.val); \ + tmp = vslideup_vx_##_T##m2(tmp, n, num2);\ + return _Tpvec(vget_##_T##m2_##_T##m1(tmp, 1));\ +} \ +template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a, const _Tpvec& b) \ +{ \ + CV_UNUSED(b); return a; \ +} + +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_uint8x16, vuint8, u8, 16, 32, vmv_v_x, b8) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_int8x16, vint8, i8, 16, 32, vmv_v_x, b8) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_uint16x8, vuint16, u16, 8, 16, vmv_v_x, b16) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_int16x8, vint16, i16, 8, 16, vmv_v_x, b16) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_uint32x4, vuint32, u32, 4, 8, vmv_v_x, b32) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_int32x4, vint32, i32, 4, 8, vmv_v_x, b32) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_uint64x2, vuint64, u64, 2, 4, vmv_v_x, b64) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_int64x2, vint64, i64, 2, 4, vmv_v_x, b64) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_float32x4, vfloat32, f32, 4, 8, vfmv_v_f, b32) +OPENCV_HAL_IMPL_RISCVV_ROTATE_OP(v_float64x2, vfloat64, f64, 2, 4, vfmv_v_f, b64) + +#define OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(_Tpvec, _Tp, _Tp2, len, hnum, num) \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ \ + typedef uint64 CV_DECL_ALIGNED(1) unaligned_uint64; \ + vuint64m1_t tmp = {*(unaligned_uint64*)ptr0, *(unaligned_uint64*)ptr1};\ + return _Tpvec(_Tp2##_t(tmp)); } \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ return _Tpvec(vle_v_##len(ptr, hnum)); }\ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(vle_v_##len(ptr, num)); } \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec((_Tp2##_t)vle_v_##len((const _Tp *)ptr, num)); } \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ vse_v_##len(ptr, a.val, hnum);}\ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ \ + _Tp2##_t a0 = vslidedown_vx_##len(a.val, hnum, num); \ + vse_v_##len(ptr, a0, hnum);}\ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ vse_v_##len(ptr, a.val, num); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ vse_v_##len(ptr, a.val, num); } \ +inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ +{ vse_v_##len(ptr, a.val, num); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode /*mode*/) \ +{ vse_v_##len(ptr, a.val, num); } + +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_uint8x16, uchar, vuint8m1, u8m1, 8, 16) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_int8x16, schar, vint8m1, i8m1, 8, 16) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_uint16x8, ushort, vuint16m1, u16m1, 4, 8) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_int16x8, short, vint16m1, i16m1, 4, 8) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_uint32x4, unsigned, vuint32m1, u32m1, 2, 4) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_int32x4, int, vint32m1, i32m1, 2, 4) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_uint64x2, unsigned long, vuint64m1, u64m1, 1, 2) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_int64x2, long, vint64m1, i64m1, 1, 2) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_float32x4, float, vfloat32m1, f32m1, 2, 4) +OPENCV_HAL_IMPL_RISCVV_LOADSTORE_OP(v_float64x2, double, vfloat64m1, f64m1, 1, 2) + + +////////////// Lookup table access //////////////////// + +inline v_int8x16 v_lut(const schar* tab, const int* idx) +{ +#if 1 + schar CV_DECL_ALIGNED(32) elems[16] = + { + tab[idx[ 0]], + tab[idx[ 1]], + tab[idx[ 2]], + tab[idx[ 3]], + tab[idx[ 4]], + tab[idx[ 5]], + tab[idx[ 6]], + tab[idx[ 7]], + tab[idx[ 8]], + tab[idx[ 9]], + tab[idx[10]], + tab[idx[11]], + tab[idx[12]], + tab[idx[13]], + tab[idx[14]], + tab[idx[15]] + }; + return v_int8x16(vle_v_i8m1(elems, 16)); +#else + int32xm4_t index32 = vlev_int32xm4(idx, 16); + vint16m2_t index16 = vnsra_vx_i16m2_int32xm4(index32, 0, 16); + vint8m1_t index = vnsra_vx_i8m1_i16m2(index16, 0, 16); + return v_int8x16(vlxbv_i8m1(tab, index, 16)); +#endif +} + +inline v_int8x16 v_lut_pairs(const schar* tab, const int* idx){ + schar CV_DECL_ALIGNED(32) elems[16] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[2]], + tab[idx[2] + 1], + tab[idx[3]], + tab[idx[3] + 1], + tab[idx[4]], + tab[idx[4] + 1], + tab[idx[5]], + tab[idx[5] + 1], + tab[idx[6]], + tab[idx[6] + 1], + tab[idx[7]], + tab[idx[7] + 1] + }; + return v_int8x16(vle_v_i8m1(elems, 16)); +} +inline v_int8x16 v_lut_quads(const schar* tab, const int* idx) +{ + schar CV_DECL_ALIGNED(32) elems[16] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[0] + 2], + tab[idx[0] + 3], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[1] + 2], + tab[idx[1] + 3], + tab[idx[2]], + tab[idx[2] + 1], + tab[idx[2] + 2], + tab[idx[2] + 3], + tab[idx[3]], + tab[idx[3] + 1], + tab[idx[3] + 2], + tab[idx[3] + 3] + }; + return v_int8x16(vle_v_i8m1(elems, 16)); +} + +inline v_uint8x16 v_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut((schar*)tab, idx)); } +inline v_uint8x16 v_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_pairs((schar*)tab, idx)); } +inline v_uint8x16 v_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_quads((schar*)tab, idx)); } + +inline v_int16x8 v_lut(const short* tab, const int* idx) +{ + short CV_DECL_ALIGNED(32) elems[8] = + { + tab[idx[0]], + tab[idx[1]], + tab[idx[2]], + tab[idx[3]], + tab[idx[4]], + tab[idx[5]], + tab[idx[6]], + tab[idx[7]] + }; + return v_int16x8(vle_v_i16m1(elems, 8)); +} +inline v_int16x8 v_lut_pairs(const short* tab, const int* idx) +{ + short CV_DECL_ALIGNED(32) elems[8] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[2]], + tab[idx[2] + 1], + tab[idx[3]], + tab[idx[3] + 1] + }; + return v_int16x8(vle_v_i16m1(elems, 8)); +} +inline v_int16x8 v_lut_quads(const short* tab, const int* idx) +{ + short CV_DECL_ALIGNED(32) elems[8] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[0] + 2], + tab[idx[0] + 3], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[1] + 2], + tab[idx[1] + 3] + }; + return v_int16x8(vle_v_i16m1(elems, 8)); +} +inline v_uint16x8 v_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut((short*)tab, idx)); } +inline v_uint16x8 v_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_pairs((short*)tab, idx)); } +inline v_uint16x8 v_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_quads((short*)tab, idx)); } + +inline v_int32x4 v_lut(const int* tab, const int* idx) +{ + int CV_DECL_ALIGNED(32) elems[4] = + { + tab[idx[0]], + tab[idx[1]], + tab[idx[2]], + tab[idx[3]] + }; + return v_int32x4(vle_v_i32m1(elems, 4)); +} +inline v_int32x4 v_lut_pairs(const int* tab, const int* idx) +{ + int CV_DECL_ALIGNED(32) elems[4] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[1]], + tab[idx[1] + 1] + }; + return v_int32x4(vle_v_i32m1(elems, 4)); +} +inline v_int32x4 v_lut_quads(const int* tab, const int* idx) +{ + return v_int32x4(vle_v_i32m1(tab+idx[0], 4)); +} +inline v_uint32x4 v_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut((int*)tab, idx)); } +inline v_uint32x4 v_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_pairs((int*)tab, idx)); } +inline v_uint32x4 v_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_quads((int*)tab, idx)); } + +inline v_int64x2 v_lut(const int64_t* tab, const int* idx) +{ + vint64m1_t res = {tab[idx[0]], tab[idx[1]]}; + return v_int64x2(res); +} +inline v_int64x2 v_lut_pairs(const int64_t* tab, const int* idx) +{ + return v_int64x2(vle_v_i64m1(tab+idx[0], 2)); +} + +inline v_uint64x2 v_lut(const uint64_t* tab, const int* idx) +{ + vuint64m1_t res = {tab[idx[0]], tab[idx[1]]}; + return v_uint64x2(res); +} +inline v_uint64x2 v_lut_pairs(const uint64_t* tab, const int* idx) +{ + return v_uint64x2(vle_v_u64m1(tab+idx[0], 2)); +} + +inline v_float32x4 v_lut(const float* tab, const int* idx) +{ + float CV_DECL_ALIGNED(32) elems[4] = + { + tab[idx[0]], + tab[idx[1]], + tab[idx[2]], + tab[idx[3]] + }; + return v_float32x4(vle_v_f32m1(elems, 4)); +} +inline v_float32x4 v_lut_pairs(const float* tab, const int* idx) +{ + float CV_DECL_ALIGNED(32) elems[4] = + { + tab[idx[0]], + tab[idx[0]+1], + tab[idx[1]], + tab[idx[1]+1] + }; + return v_float32x4(vle_v_f32m1(elems, 4)); +} +inline v_float32x4 v_lut_quads(const float* tab, const int* idx) +{ + return v_float32x4(vle_v_f32m1(tab + idx[0], 4)); +} +inline v_float64x2 v_lut(const double* tab, const int* idx) +{ + vfloat64m1_t res = {tab[idx[0]], tab[idx[1]]}; + return v_float64x2(res); +} +inline v_float64x2 v_lut_pairs(const double* tab, const int* idx) +{ + return v_float64x2(vle_v_f64m1(tab+idx[0], 2)); +} + +inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec) +{ + int CV_DECL_ALIGNED(32) elems[4] = + { + tab[idxvec.val[0]], + tab[idxvec.val[1]], + tab[idxvec.val[2]], + tab[idxvec.val[3]] + }; + return v_int32x4(vle_v_i32m1(elems, 4)); +} + +inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec) +{ + unsigned CV_DECL_ALIGNED(32) elems[4] = + { + tab[idxvec.val[0]], + tab[idxvec.val[1]], + tab[idxvec.val[2]], + tab[idxvec.val[3]] + }; + return v_uint32x4(vle_v_u32m1(elems, 4)); +} + +inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec) +{ + float CV_DECL_ALIGNED(32) elems[4] = + { + tab[idxvec.val[0]], + tab[idxvec.val[1]], + tab[idxvec.val[2]], + tab[idxvec.val[3]] + }; + return v_float32x4(vle_v_f32m1(elems, 4)); +} +inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec) +{ + vfloat64m1_t res = {tab[idxvec.val[0]], tab[idxvec.val[1]]}; + return v_float64x2(res); +} +inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y) +{ + vint32m1_t index_x = vmul_vx_i32m1(idxvec.val, 4, 4); + vint32m1_t index_y = vadd_vx_i32m1(index_x, 4, 4); + + x.val = vlxe_v_f32m1(tab, index_x, 4); + y.val = vlxe_v_f32m1(tab, index_y, 4); +} + +inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y) +{ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_aligned(idx, idxvec); + + x = v_float64x2(tab[idx[0]], tab[idx[1]]); + y = v_float64x2(tab[idx[0]+1], tab[idx[1]+1]); +} + +#define OPENCV_HAL_IMPL_RISCVV_PACKS(_Tp, _Tp2, _T2, num2, _T1, num, intrin, shr, _Type) \ +inline v_##_Tp##x##num v_pack(const v_##_Tp2##x##num2& a, const v_##_Tp2##x##num2& b) \ +{ \ + v##_Tp2##m2_t tmp = vundefined_##_T2##m2(); \ + tmp = vset_##_T2##m2(tmp, 0, a.val); \ + tmp = vset_##_T2##m2(tmp, 1, b.val); \ + return v_##_Tp##x##num(shr##_##_T1##m1(tmp, 0, num)); \ +}\ +template inline \ +v_##_Tp##x##num v_rshr_pack(const v_##_Tp2##x##num2& a, const v_##_Tp2##x##num2& b) \ +{ \ + v##_Tp2##m2_t tmp = vundefined_##_T2##m2(); \ + tmp = vset_##_T2##m2(tmp, 0, a.val); \ + tmp = vset_##_T2##m2(tmp, 1, b.val); \ + return v_##_Tp##x##num(intrin##_##_T1##m1(tmp, n, num)); \ +}\ +inline void v_pack_store(_Type* ptr, const v_##_Tp2##x##num2& a) \ +{ \ + v##_Tp2##m2_t tmp = vundefined_##_T2##m2(); \ + tmp = vset_##_T2##m2(tmp, 0, a.val); \ + tmp = vset_##_T2##m2(tmp, 1, vmv_v_x_##_T2##m1(0, num2)); \ + asm("" ::: "memory"); \ + vse_v_##_T1##m1(ptr, shr##_##_T1##m1(tmp, 0, num), num2); \ +}\ +template inline \ +void v_rshr_pack_store(_Type* ptr, const v_##_Tp2##x##num2& a) \ +{ \ + v##_Tp2##m2_t tmp = vundefined_##_T2##m2(); \ + tmp = vset_##_T2##m2(tmp, 0, a.val); \ + tmp = vset_##_T2##m2(tmp, 1, vmv_v_x_##_T2##m1(0, num2)); \ + vse_v_##_T1##m1(ptr, intrin##_##_T1##m1(tmp, n, num), num2); \ +} +OPENCV_HAL_IMPL_RISCVV_PACKS(int8, int16, i16, 8, i8, 16, vnclip_vx, vnclip_vx, signed char) +OPENCV_HAL_IMPL_RISCVV_PACKS(int16, int32, i32, 4, i16, 8, vnclip_vx, vnclip_vx, signed short) +OPENCV_HAL_IMPL_RISCVV_PACKS(int32, int64, i64, 2, i32, 4, vnclip_vx, vnsra_vx, int) +OPENCV_HAL_IMPL_RISCVV_PACKS(uint8, uint16, u16, 8, u8, 16, vnclipu_vx, vnclipu_vx, unsigned char) +OPENCV_HAL_IMPL_RISCVV_PACKS(uint16, uint32, u32, 4, u16, 8, vnclipu_vx, vnclipu_vx, unsigned short) +OPENCV_HAL_IMPL_RISCVV_PACKS(uint32, uint64, u64, 2, u32, 4, vnclipu_vx, vnsrl_vx, unsigned int) + +// pack boolean +inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b) +{ + vuint16m2_t tmp = vundefined_u16m2(); \ + tmp = vset_u16m2(tmp, 0, a.val); \ + tmp = vset_u16m2(tmp, 1, b.val); \ + return v_uint8x16(vnsrl_vx_u8m1(tmp, 0, 16)); +} + +inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, const v_uint32x4& d) +{ + vuint32m4_t vabcd = vundefined_u32m4(); \ + vuint16m2_t v16 = vundefined_u16m2(); \ + vabcd = vset_u32m4(vabcd, 0, a.val); \ + vabcd = vset_u32m4(vabcd, 1, b.val); \ + vabcd = vset_u32m4(vabcd, 2, c.val); \ + vabcd = vset_u32m4(vabcd, 3, d.val); \ + v16 = vnsrl_vx_u16m2(vabcd, 0, 16); + return v_uint8x16(vnsrl_vx_u8m1(v16, 0, 16)); +} + +inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c, + const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f, + const v_uint64x2& g, const v_uint64x2& h) +{ + vuint64m8_t v64 = vundefined_u64m8(); \ + vuint32m4_t v32 = vundefined_u32m4(); \ + vuint16m2_t v16 = vundefined_u16m2(); \ + v64 = vset_u64m8(v64, 0, a.val); \ + v64 = vset_u64m8(v64, 1, b.val); \ + v64 = vset_u64m8(v64, 2, c.val); \ + v64 = vset_u64m8(v64, 3, d.val); \ + v64 = vset_u64m8(v64, 4, e.val); \ + v64 = vset_u64m8(v64, 5, f.val); \ + v64 = vset_u64m8(v64, 6, g.val); \ + v64 = vset_u64m8(v64, 7, h.val); \ + v32 = vnsrl_vx_u32m4(v64, 0, 16); + v16 = vnsrl_vx_u16m2(v32, 0, 16); + return v_uint8x16(vnsrl_vx_u8m1(v16, 0, 16)); +} + +//inline v_uint8x16 v_pack_u(const v_int16x8& a, const v_int16x8& b) \ +//{ \ +// int16xm2_u tmp; \ +// tmp.m1[0] = (vint16m1_t)a.val; \ +// tmp.m1[1] = (vint16m1_t)b.val; \ +// e8xm1_t mask = (e8xm1_t)vmsge_vx_e16xm2_i16m2(tmp.v, 0, 16);\ +// return v_uint8x16(vnclipuvi_mask_u8m1_u16m2(vmv_v_x_u8m1(0, 16), (vuint16m2_t)tmp.v, 0, mask, 16)); +//} + +#define OPENCV_HAL_IMPL_RISCVV_PACK_U(tp1, num1, tp2, num2, _Tp) \ +inline v_uint##tp1##x##num1 v_pack_u(const v_int##tp2##x##num2& a, const v_int##tp2##x##num2& b) \ +{ \ + vint##tp2##m2_t tmp = vundefined_##i##tp2##m2(); \ + tmp = vset_##i##tp2##m2(tmp, 0, a.val); \ + tmp = vset_##i##tp2##m2(tmp, 1, b.val); \ + vint##tp2##m2_t val = vmax_vx_i##tp2##m2(tmp, 0, num1);\ + return v_uint##tp1##x##num1(vnclipu_vx_u##tp1##m1((vuint##tp2##m2_t)val, 0, num1)); \ +} \ +inline void v_pack_u_store(_Tp* ptr, const v_int##tp2##x##num2& a) \ +{ \ + vint##tp2##m2_t tmp = vundefined_##i##tp2##m2(); \ + tmp = vset_##i##tp2##m2(tmp, 0, a.val); \ + vint##tp2##m2_t val = vmax_vx_i##tp2##m2(tmp, 0, num1);\ + return vse_v_u##tp1##m1(ptr, vnclipu_vx_u##tp1##m1((vuint##tp2##m2_t)val, 0, num1), num2); \ +} \ +template inline \ +v_uint##tp1##x##num1 v_rshr_pack_u(const v_int##tp2##x##num2& a, const v_int##tp2##x##num2& b) \ +{ \ + vint##tp2##m2_t tmp = vundefined_##i##tp2##m2(); \ + tmp = vset_##i##tp2##m2(tmp, 0, a.val); \ + tmp = vset_##i##tp2##m2(tmp, 1, b.val); \ + vint##tp2##m2_t val = vmax_vx_i##tp2##m2(tmp, 0, num1);\ + return v_uint##tp1##x##num1(vnclipu_vx_u##tp1##m1((vuint##tp2##m2_t)val, n, num1)); \ +} \ +template inline \ +void v_rshr_pack_u_store(_Tp* ptr, const v_int##tp2##x##num2& a) \ +{ \ + vint##tp2##m2_t tmp = vundefined_##i##tp2##m2(); \ + tmp = vset_##i##tp2##m2(tmp, 0, a.val); \ + vint##tp2##m2_t val_ = vmax_vx_i##tp2##m2(tmp, 0, num1);\ + vuint##tp1##m1_t val = vnclipu_vx_u##tp1##m1((vuint##tp2##m2_t)val_, n, num1); \ + return vse_v_u##tp1##m1(ptr, val, num2);\ +} +OPENCV_HAL_IMPL_RISCVV_PACK_U(8, 16, 16, 8, unsigned char ) +OPENCV_HAL_IMPL_RISCVV_PACK_U(16, 8, 32, 4, unsigned short) + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + +// saturating multiply 8-bit, 16-bit +#define OPENCV_HAL_IMPL_RISCVV_MUL_SAT(_Tpvec, _Tpwvec) \ + inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \ + { \ + _Tpwvec c, d; \ + v_mul_expand(a, b, c, d); \ + return v_pack(c, d); \ + } \ + inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \ + { a = a * b; return a; } + +OPENCV_HAL_IMPL_RISCVV_MUL_SAT(v_int8x16, v_int16x8) +OPENCV_HAL_IMPL_RISCVV_MUL_SAT(v_uint8x16, v_uint16x8) +OPENCV_HAL_IMPL_RISCVV_MUL_SAT(v_int16x8, v_int32x4) +OPENCV_HAL_IMPL_RISCVV_MUL_SAT(v_uint16x8, v_uint32x4) + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif +static const signed char popCountTable[256] = +{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, +}; + +inline vuint8m1_t vcnt_u8(vuint8m1_t val){ + vuint8m1_t v0 = val & 1; + return vlxe_v_u8m1((unsigned char*)popCountTable, val >> 1, 16)+v0; +} + +inline v_uint8x16 +v_popcount(const v_uint8x16& a) +{ + return v_uint8x16(vcnt_u8(a.val)); +} + +inline v_uint8x16 +v_popcount(const v_int8x16& a) +{ + return v_uint8x16(vcnt_u8((vuint8m1_t)a.val)); +} + +inline v_uint16x8 +v_popcount(const v_uint16x8& a) +{ + vuint8m2_t tmp = vundefined_u8m2(); + tmp = vset_u8m2(tmp, 0, vcnt_u8((vuint8m1_t)a.val)); + vuint64m2_t mask = (vuint64m2_t){0x0E0C0A0806040200, 0, 0x0F0D0B0907050301, 0}; + tmp = vrgather_vv_u8m2(tmp, (vuint8m2_t)mask, 32); \ + vuint16m2_t res = vwaddu_vv_u16m2(vget_u8m2_u8m1(tmp, 0), vget_u8m2_u8m1(tmp, 1), 8); + return v_uint16x8(vget_u16m2_u16m1(res, 0)); +} + +inline v_uint16x8 +v_popcount(const v_int16x8& a) +{ + vuint8m2_t tmp = vundefined_u8m2(); + tmp = vset_u8m2(tmp, 0, vcnt_u8((vuint8m1_t)a.val)); + vuint64m2_t mask = (vuint64m2_t){0x0E0C0A0806040200, 0, 0x0F0D0B0907050301, 0}; + tmp = vrgather_vv_u8m2(tmp, (vuint8m2_t)mask, 32); \ + vuint16m2_t res = vwaddu_vv_u16m2(vget_u8m2_u8m1(tmp, 0), vget_u8m2_u8m1(tmp, 1), 8); + return v_uint16x8(vget_u16m2_u16m1(res, 0)); +} + +inline v_uint32x4 +v_popcount(const v_uint32x4& a) +{ + vuint8m2_t tmp = vundefined_u8m2(); + tmp = vset_u8m2(tmp, 0, vcnt_u8((vuint8m1_t)a.val)); + vuint64m2_t mask = (vuint64m2_t){0xFFFFFFFF0C080400, 0xFFFFFFFF0D090501, + 0xFFFFFFFF0E0A0602, 0xFFFFFFFF0F0B0703}; + tmp = vrgather_vv_u8m2(tmp, (vuint8m2_t)mask, 32); \ + vuint16m2_t res_ = vwaddu_vv_u16m2(vget_u8m2_u8m1(tmp, 0), vget_u8m2_u8m1(tmp, 1), 16); + vuint32m2_t res = vwaddu_vv_u32m2(vget_u16m2_u16m1(res_, 0), vget_u16m2_u16m1(res_, 1), 8); + return v_uint32x4(vget_u32m2_u32m1(res, 0)); +} + +inline v_uint32x4 +v_popcount(const v_int32x4& a) +{ + vuint8m2_t tmp = vundefined_u8m2(); + tmp = vset_u8m2(tmp, 0, vcnt_u8((vuint8m1_t)a.val)); + vuint64m2_t mask = (vuint64m2_t){0xFFFFFFFF0C080400, 0xFFFFFFFF0D090501, + 0xFFFFFFFF0E0A0602, 0xFFFFFFFF0F0B0703}; + tmp = vrgather_vv_u8m2(tmp, (vuint8m2_t)mask, 32); \ + vuint16m2_t res_ = vwaddu_vv_u16m2(vget_u8m2_u8m1(tmp, 0), vget_u8m2_u8m1(tmp, 1), 16); + vuint32m2_t res = vwaddu_vv_u32m2(vget_u16m2_u16m1(res_, 0), vget_u16m2_u16m1(res_, 1), 8); + return v_uint32x4(vget_u32m2_u32m1(res, 0)); +} + +inline v_uint64x2 +v_popcount(const v_uint64x2& a) +{ + vuint8m2_t tmp = vundefined_u8m2(); + tmp = vset_u8m2(tmp, 0, vcnt_u8((vuint8m1_t)a.val)); + vuint64m2_t mask = (vuint64m2_t){0x0706050403020100, 0x0000000000000000, + 0x0F0E0D0C0B0A0908, 0x0000000000000000}; + tmp = vrgather_vv_u8m2(tmp, (vuint8m2_t)mask, 32); \ + vuint8m1_t zero = vmv_v_x_u8m1(0, 16); + vuint8m1_t res1 = zero; + vuint8m1_t res2 = zero; + res1 = vredsum_vs_u8m1_u8m1(res1, vget_u8m2_u8m1(tmp, 0), zero, 8); + res2 = vredsum_vs_u8m1_u8m1(res2, vget_u8m2_u8m1(tmp, 1), zero, 8); + + return v_uint64x2((unsigned long)vmv_x_s_u8m1_u8(res1, 8), (unsigned long)vmv_x_s_u8m1_u8(res2, 8)); +} + +inline v_uint64x2 +v_popcount(const v_int64x2& a) +{ + vuint8m2_t tmp = vundefined_u8m2(); + tmp = vset_u8m2(tmp, 0, vcnt_u8((vuint8m1_t)a.val)); + vuint64m2_t mask = (vuint64m2_t){0x0706050403020100, 0x0000000000000000, + 0x0F0E0D0C0B0A0908, 0x0000000000000000}; + tmp = vrgather_vv_u8m2(tmp, (vuint8m2_t)mask, 32); \ + vuint8m1_t zero = vmv_v_x_u8m1(0, 16); + vuint8m1_t res1 = zero; + vuint8m1_t res2 = zero; + res1 = vredsum_vs_u8m1_u8m1(res1, vget_u8m2_u8m1(tmp, 0), zero, 8); + res2 = vredsum_vs_u8m1_u8m1(res2, vget_u8m2_u8m1(tmp, 1), zero, 8); + + return v_uint64x2((unsigned long)vmv_x_s_u8m1_u8(res1, 8), (unsigned long)vmv_x_s_u8m1_u8(res2, 8)); +} + +#define SMASK 1, 2, 4, 8, 16, 32, 64, 128 +inline int v_signmask(const v_uint8x16& a) +{ + vuint8m1_t t0 = vsrl_vx_u8m1(a.val, 7, 16); + vuint8m1_t m1 = (vuint8m1_t){SMASK, SMASK}; + vuint16m2_t t1 = vwmulu_vv_u16m2(t0, m1, 16); + vuint32m1_t res = vmv_v_x_u32m1(0, 4); + vuint32m2_t t2 = vwmulu_vx_u32m2(vget_u16m2_u16m1(t1, 1), 256, 8); + res = vredsum_vs_u32m2_u32m1(res, t2, res, 8); + res = vwredsumu_vs_u16m1_u32m1(res, vget_u16m2_u16m1(t1, 0), res, 8); + return vmv_x_s_u32m1_u32(res, 8); +} +inline int v_signmask(const v_int8x16& a) +{ + vuint8m1_t t0 = vsrl_vx_u8m1((vuint8m1_t)a.val, 7, 16); + vuint8m1_t m1 = (vuint8m1_t){SMASK, SMASK}; + vint16m2_t t1 = (vint16m2_t)vwmulu_vv_u16m2(t0, m1, 16); + vint32m1_t res = vmv_v_x_i32m1(0, 4); + vint32m2_t t2 = vwmul_vx_i32m2(vget_i16m2_i16m1(t1, 1), 256, 8); + res = vredsum_vs_i32m2_i32m1(res, t2, res, 8); + res = vwredsum_vs_i16m1_i32m1(res, vget_i16m2_i16m1(t1, 0), res, 8); + return vmv_x_s_i32m1_i32(res, 8); +} + +inline int v_signmask(const v_int16x8& a) +{ + vint16m1_t t0 = (vint16m1_t)vsrl_vx_u16m1((vuint16m1_t)a.val, 15, 8); + vint16m1_t m1 = (vint16m1_t){SMASK}; + vint16m1_t t1 = vmul_vv_i16m1(t0, m1, 8); + vint16m1_t res = vmv_v_x_i16m1(0, 8); + res = vredsum_vs_i16m1_i16m1(res, t1, res, 8); + return vmv_x_s_i16m1_i16(res, 8); +} +inline int v_signmask(const v_uint16x8& a) +{ + vint16m1_t t0 = (vint16m1_t)vsrl_vx_u16m1((vuint16m1_t)a.val, 15, 8); + vint16m1_t m1 = (vint16m1_t){SMASK}; + vint16m1_t t1 = vmul_vv_i16m1(t0, m1, 8); + vint16m1_t res = vmv_v_x_i16m1(0, 8); + res = vredsum_vs_i16m1_i16m1(res, t1, res, 8); + return vmv_x_s_i16m1_i16(res, 8); +} +inline int v_signmask(const v_int32x4& a) +{ + vint32m1_t t0 = (vint32m1_t)vsrl_vx_u32m1((vuint32m1_t)a.val, 31, 4); + vint32m1_t m1 = (vint32m1_t){1, 2, 4, 8}; + vint32m1_t res = vmv_v_x_i32m1(0, 4); + vint32m1_t t1 = vmul_vv_i32m1(t0, m1, 4); + res = vredsum_vs_i32m1_i32m1(res, t1, res, 4); + return vmv_x_s_i32m1_i32(res, 4); +} +inline int v_signmask(const v_uint32x4& a) +{ + vint32m1_t t0 = (vint32m1_t)vsrl_vx_u32m1(a.val, 31, 4); + vint32m1_t m1 = (vint32m1_t){1, 2, 4, 8}; + vint32m1_t res = vmv_v_x_i32m1(0, 4); + vint32m1_t t1 = vmul_vv_i32m1(t0, m1, 4); + res = vredsum_vs_i32m1_i32m1(res, t1, res, 4); + return vmv_x_s_i32m1_i32(res, 4); +} +inline int v_signmask(const v_uint64x2& a) +{ + vuint64m1_t v0 = vsrl_vx_u64m1(a.val, 63, 2); + int res = (int)vext_x_v_u64m1_u64(v0, 0, 2) + ((int)vext_x_v_u64m1_u64(v0, 1, 2) << 1); + return res; +} +inline int v_signmask(const v_int64x2& a) +{ return v_signmask(v_reinterpret_as_u64(a)); } +inline int v_signmask(const v_float64x2& a) +{ return v_signmask(v_reinterpret_as_u64(a)); } +inline int v_signmask(const v_float32x4& a) +{ + vint32m1_t t0 = (vint32m1_t)vsrl_vx_u32m1((vuint32m1_t)a.val, 31, 4); + vint32m1_t m1 = (vint32m1_t){1, 2, 4, 8}; + vint32m1_t res = vmv_v_x_i32m1(0, 4); + vint32m1_t t1 = vmul_vv_i32m1(t0, m1, 4); + res = vredsum_vs_i32m1_i32m1(res, t1, res, 4); + return vmv_x_s_i32m1_i32(res, 4); +} + +inline int v_scan_forward(const v_int8x16& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_uint8x16& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_int16x8& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_uint16x8& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_int32x4& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_uint32x4& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_float32x4& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_int64x2& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } +inline int v_scan_forward(const v_uint64x2& a) { +int val = v_signmask(a); +if(val==0) return 0; +else return trailingZeros32(val); } + +#define OPENCV_HAL_IMPL_RISCVV_CHECK_ALLANY(_Tpvec, suffix, _T, shift, num) \ +inline bool v_check_all(const v_##_Tpvec& a) \ +{ \ + suffix##m1_t v0 = vsrl_vx_##_T(vnot_v_##_T(a.val, num), shift, num); \ + vuint64m1_t v1 = vuint64m1_t(v0); \ + return (v1[0] | v1[1]) == 0; \ +} \ +inline bool v_check_any(const v_##_Tpvec& a) \ +{ \ + suffix##m1_t v0 = vsrl_vx_##_T(a.val, shift, num); \ + vuint64m1_t v1 = vuint64m1_t(v0); \ + return (v1[0] | v1[1]) != 0; \ +} + +OPENCV_HAL_IMPL_RISCVV_CHECK_ALLANY(uint8x16, vuint8, u8m1, 7, 16) +OPENCV_HAL_IMPL_RISCVV_CHECK_ALLANY(uint16x8, vuint16, u16m1, 15, 8) +OPENCV_HAL_IMPL_RISCVV_CHECK_ALLANY(uint32x4, vuint32, u32m1, 31, 4) +OPENCV_HAL_IMPL_RISCVV_CHECK_ALLANY(uint64x2, vuint64, u64m1, 63, 2) + +inline bool v_check_all(const v_int8x16& a) +{ return v_check_all(v_reinterpret_as_u8(a)); } +inline bool v_check_all(const v_int16x8& a) +{ return v_check_all(v_reinterpret_as_u16(a)); } +inline bool v_check_all(const v_int32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } +inline bool v_check_all(const v_float32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } +inline bool v_check_all(const v_int64x2& a) +{ return v_check_all(v_reinterpret_as_u64(a)); } +inline bool v_check_all(const v_float64x2& a) +{ return v_check_all(v_reinterpret_as_u64(a)); } + +inline bool v_check_any(const v_int8x16& a) +{ return v_check_any(v_reinterpret_as_u8(a)); } +inline bool v_check_any(const v_int16x8& a) +{ return v_check_any(v_reinterpret_as_u16(a)); } +inline bool v_check_any(const v_int32x4& a) +{ return v_check_any(v_reinterpret_as_u32(a)); } +inline bool v_check_any(const v_float32x4& a) +{ return v_check_any(v_reinterpret_as_u32(a)); } +inline bool v_check_any(const v_int64x2& a) +{ return v_check_any(v_reinterpret_as_u64(a)); } +inline bool v_check_any(const v_float64x2& a) +{ return v_check_any(v_reinterpret_as_u64(a)); } + +#define OPENCV_HAL_IMPL_RISCVV_SELECT(_Tpvec, suffix, _Tpvec2, num) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(vmerge_vvm_##suffix(_Tpvec2(mask.val), b.val, a.val, num)); \ +} + +OPENCV_HAL_IMPL_RISCVV_SELECT(v_int8x16, i8m1, vbool8_t, 16) +OPENCV_HAL_IMPL_RISCVV_SELECT(v_int16x8, i16m1, vbool16_t, 8) +OPENCV_HAL_IMPL_RISCVV_SELECT(v_int32x4, i32m1, vbool32_t, 4) +OPENCV_HAL_IMPL_RISCVV_SELECT(v_uint8x16, u8m1, vbool8_t, 16) +OPENCV_HAL_IMPL_RISCVV_SELECT(v_uint16x8, u16m1, vbool16_t, 8) +OPENCV_HAL_IMPL_RISCVV_SELECT(v_uint32x4, u32m1, vbool32_t, 4) +inline v_float32x4 v_select(const v_float32x4& mask, const v_float32x4& a, const v_float32x4& b) +{ + return v_float32x4((vfloat32m1_t)vmerge_vvm_u32m1((vbool32_t)mask.val, (vuint32m1_t)b.val, (vuint32m1_t)a.val, 4)); +} +inline v_float64x2 v_select(const v_float64x2& mask, const v_float64x2& a, const v_float64x2& b) +{ + return v_float64x2((vfloat64m1_t)vmerge_vvm_u64m1((vbool64_t)mask.val, (vuint64m1_t)b.val, (vuint64m1_t)a.val, 2)); +} + +#define OPENCV_HAL_IMPL_RISCVV_EXPAND(add, _Tpvec, _Tpwvec, _Tp, _Tp1, num1, _Tp2, num2, _T1, _T2) \ +inline void v_expand(const _Tpvec& a, v_##_Tpwvec& b0, v_##_Tpwvec& b1) \ +{ \ + _T1##_t b = vw##add##_vv_##_Tp2##m2(a.val, vmv_v_x_##_Tp1(0, num1), num1); \ + b0.val = vget_##_Tp2##m2_##_Tp2##m1(b, 0); \ + b1.val = vget_##_Tp2##m2_##_Tp2##m1(b, 1); \ +} \ +inline v_##_Tpwvec v_expand_low(const _Tpvec& a) \ +{ \ + _T1##_t b = vw##add##_vv_##_Tp2##m2(a.val, vmv_v_x_##_Tp1(0, num2), num2); \ + return v_##_Tpwvec(vget_##_Tp2##m2_##_Tp2##m1(b, 0)); \ +} \ +inline v_##_Tpwvec v_expand_high(const _Tpvec& a) \ +{ \ + _T1##_t b = vw##add##_vv_##_Tp2##m2(a.val, vmv_v_x_##_Tp1(0, num1), num1); \ + return v_##_Tpwvec(vget_##_Tp2##m2_##_Tp2##m1(b, 1)); \ +} \ +inline v_##_Tpwvec v_load_expand(const _Tp* ptr) \ +{ \ + _T2##_t val = vle##_v_##_Tp1(ptr, num2); \ + _T1##_t b = vw##add##_vv_##_Tp2##m2(val, vmv_v_x_##_Tp1(0, num2), num2); \ + return v_##_Tpwvec(vget_##_Tp2##m2_##_Tp2##m1(b, 0)); \ +} + +OPENCV_HAL_IMPL_RISCVV_EXPAND(addu, v_uint8x16, uint16x8, uchar, u8m1, 16, u16, 8, vuint16m2, vuint8m1) +OPENCV_HAL_IMPL_RISCVV_EXPAND(addu, v_uint16x8, uint32x4, ushort, u16m1, 8, u32, 4, vuint32m2, vuint16m1) +OPENCV_HAL_IMPL_RISCVV_EXPAND(addu, v_uint32x4, uint64x2, uint, u32m1, 4, u64, 2, vuint64m2, vuint32m1) +OPENCV_HAL_IMPL_RISCVV_EXPAND(add, v_int8x16, int16x8, schar, i8m1, 16, i16, 8, vint16m2, vint8m1) +OPENCV_HAL_IMPL_RISCVV_EXPAND(add, v_int16x8, int32x4, short, i16m1, 8, i32, 4, vint32m2, vint16m1) +OPENCV_HAL_IMPL_RISCVV_EXPAND(add, v_int32x4, int64x2, int, i32m1, 4, i64, 2, vint64m2, vint32m1) + +inline v_uint32x4 v_load_expand_q(const uchar* ptr) +{ + vuint16m2_t b = vundefined_u16m2(); + vuint32m2_t c = vundefined_u32m2(); + vuint8m1_t val = vle_v_u8m1(ptr, 4); \ + b = vwaddu_vv_u16m2(val, vmv_v_x_u8m1(0, 4), 4); \ + c = vwaddu_vv_u32m2(vget_u16m2_u16m1(b, 0), vmv_v_x_u16m1(0, 4), 4); \ + return v_uint32x4(vget_u32m2_u32m1(c, 0)); +} + +inline v_int32x4 v_load_expand_q(const schar* ptr) +{ + vint16m2_t b = vundefined_i16m2(); + vint32m2_t c = vundefined_i32m2(); + vint8m1_t val = vle_v_i8m1(ptr, 4); \ + b = vwadd_vv_i16m2(val, vmv_v_x_i8m1(0, 4), 4); \ + c = vwadd_vv_i32m2(vget_i16m2_i16m1(b, 0), vmv_v_x_i16m1(0, 4), 4); \ + return v_int32x4(vget_i32m2_i32m1(c, 0)); +} +#define VITL_16 (vuint64m2_t){0x1303120211011000, 0x1707160615051404, 0x1B0B1A0A19091808, 0x1F0F1E0E1D0D1C0C} +#define VITL_8 (vuint64m2_t){0x0009000100080000, 0x000B0003000A0002, 0x000D0005000C0004, 0x000F0007000E0006} +#define VITL_4 (vuint64m2_t){0x0000000400000000, 0x0000000500000001, 0x0000000600000002, 0x0000000700000003} +#define VITL_2 (vuint64m2_t){0, 2, 1, 3} +#define LOW_4 0x0000000100000000, 0x0000000500000004 +#define LOW_8 0x0003000200010000, 0x000B000A00090008 +#define LOW_16 0x0706050403020100, 0x1716151413121110 +#define HIGH_4 0x0000000300000002, 0x0000000700000006 +#define HIGH_8 0x0007000600050004, 0x000F000E000D000C +#define HIGH_16 0x0F0E0D0C0B0A0908, 0x1F1E1D1C1B1A1918 +#define OPENCV_HAL_IMPL_RISCVV_UNPACKS(_Tpvec, _Tp, _T, _UTp, _UT, num, num2, len, numh) \ +inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \ +{ \ + v##_Tp##m2_t tmp = vundefined_##_T##m2();\ + tmp = vset_##_T##m2(tmp, 0, a0.val); \ + tmp = vset_##_T##m2(tmp, 1, a1.val); \ + vuint64m2_t mask = VITL_##num; \ + tmp = (v##_Tp##m2_t)vrgather_vv_##_T##m2((v##_Tp##m2_t)tmp, (v##_UTp##m2_t)mask, num2); \ + b0.val = vget_##_T##m2_##_T##m1(tmp, 0); \ + b1.val = vget_##_T##m2_##_T##m1(tmp, 1); \ +} \ +inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + v##_Tp##m1_t b0 = vslideup_vx_##_T##m1_m(vmset_m_##len(num), a.val, b.val, numh, num); \ + return v_##_Tpvec(b0);\ +} \ +inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + v##_Tp##m1_t b0 = vslidedown_vx_##_T##m1(b.val, numh, num); \ + v##_Tp##m1_t a0 = vslidedown_vx_##_T##m1(a.val, numh, num); \ + v##_Tp##m1_t b1 = vslideup_vx_##_T##m1_m(vmset_m_##len(num), a0, b0, numh, num); \ + return v_##_Tpvec(b1);\ +} \ +inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \ +{ \ + c.val = vslideup_vx_##_T##m1_m(vmset_m_##len(num), a.val, b.val, numh, num); \ + v##_Tp##m1_t b0 = vslidedown_vx_##_T##m1(b.val, numh, num); \ + v##_Tp##m1_t a0 = vslidedown_vx_##_T##m1(a.val, numh, num); \ + d.val = vslideup_vx_##_T##m1_m(vmset_m_##len(num), a0, b0, numh, num); \ +} + +OPENCV_HAL_IMPL_RISCVV_UNPACKS(uint8x16, uint8, u8, uint8, u8, 16, 32, b8, 8) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(int8x16, int8, i8, uint8, u8, 16, 32, b8, 8) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(uint16x8, uint16, u16, uint16, u16, 8, 16, b16, 4) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(int16x8, int16, i16, uint16, u16, 8, 16, b16, 4) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(uint32x4, uint32, u32, uint32, u32, 4, 8, b32, 2) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(int32x4, int32, i32, uint32, u32, 4, 8, b32, 2) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(float32x4, float32, f32, uint32, u32, 4, 8, b32, 2) +OPENCV_HAL_IMPL_RISCVV_UNPACKS(float64x2, float64, f64, uint64, u64, 2, 4, b64, 1) + +inline v_uint8x16 v_reverse(const v_uint8x16 &a) +{ + vuint64m1_t mask = (vuint64m1_t){0x08090A0B0C0D0E0F, 0x0001020304050607}; + return v_uint8x16(vrgather_vv_u8m1(a.val, (vuint8m1_t)mask, 16)); +} +inline v_int8x16 v_reverse(const v_int8x16 &a) +{ + vint64m1_t mask = (vint64m1_t){0x08090A0B0C0D0E0F, 0x0001020304050607}; + return v_int8x16(vrgather_vv_i8m1(a.val, (vuint8m1_t)mask, 16)); +} + +inline v_uint16x8 v_reverse(const v_uint16x8 &a) +{ + vuint64m1_t mask = (vuint64m1_t){0x0004000500060007, 0x000000100020003}; + return v_uint16x8(vrgather_vv_u16m1(a.val, (vuint16m1_t)mask, 8)); +} + +inline v_int16x8 v_reverse(const v_int16x8 &a) +{ + vint64m1_t mask = (vint64m1_t){0x0004000500060007, 0x000000100020003}; + return v_int16x8(vrgather_vv_i16m1(a.val, (vuint16m1_t)mask, 8)); +} +inline v_uint32x4 v_reverse(const v_uint32x4 &a) +{ + return v_uint32x4(vrgather_vv_u32m1(a.val, (vuint32m1_t){3, 2, 1, 0}, 4)); +} + +inline v_int32x4 v_reverse(const v_int32x4 &a) +{ + return v_int32x4(vrgather_vv_i32m1(a.val, (vuint32m1_t){3, 2, 1, 0}, 4)); +} + +inline v_float32x4 v_reverse(const v_float32x4 &a) +{ return v_reinterpret_as_f32(v_reverse(v_reinterpret_as_u32(a))); } + +inline v_uint64x2 v_reverse(const v_uint64x2 &a) +{ + return v_uint64x2(a.val[1], a.val[0]); +} + +inline v_int64x2 v_reverse(const v_int64x2 &a) +{ + return v_int64x2(a.val[1], a.val[0]); +} + +inline v_float64x2 v_reverse(const v_float64x2 &a) +{ + return v_float64x2(a.val[1], a.val[0]); +} + +#define OPENCV_HAL_IMPL_RISCVV_EXTRACT(_Tpvec, suffix, size) \ +template \ +inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) \ +{ return v_rotate_right(a, b);} +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_uint8x16, u8, 0) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_int8x16, s8, 0) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_uint16x8, u16, 1) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_int16x8, s16, 1) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_uint32x4, u32, 2) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_int32x4, s32, 2) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_uint64x2, u64, 3) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_int64x2, s64, 3) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_float32x4, f32, 2) +OPENCV_HAL_IMPL_RISCVV_EXTRACT(v_float64x2, f64, 3) + + +#define OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(_Tpvec, _Tp, suffix) \ +template inline _Tp v_extract_n(_Tpvec v) { return v.val[i]; } + +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_int16x8, short, s16) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_uint32x4, uint, u32) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_int32x4, int, s32) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_uint64x2, uint64, u64) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_int64x2, int64, s64) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_float32x4, float, f32) +OPENCV_HAL_IMPL_RISCVV_EXTRACT_N(v_float64x2, double, f64) + +#define OPENCV_HAL_IMPL_RISCVV_BROADCAST(_Tpvec, _Tp, num) \ +template inline _Tpvec v_broadcast_element(_Tpvec v) { return _Tpvec(vrgather_vx_##_Tp##m1(v.val, i, num)); } + +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_uint8x16, u8, 16) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_int8x16, i8, 16) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_uint16x8, u16, 8) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_int16x8, i16, 8) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_uint32x4, u32, 4) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_int32x4, i32, 4) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_uint64x2, u64, 2) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_int64x2, i64, 2) +OPENCV_HAL_IMPL_RISCVV_BROADCAST(v_float32x4, f32, 4) +inline v_int32x4 v_round(const v_float32x4& a) +{ + __builtin_riscv_fsrm(0); + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)a.val, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), a.val, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} +inline v_int32x4 v_floor(const v_float32x4& a) +{ + __builtin_riscv_fsrm(2); + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)a.val, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), a.val, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} + +inline v_int32x4 v_ceil(const v_float32x4& a) +{ + __builtin_riscv_fsrm(3); + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)a.val, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), a.val, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} + +inline v_int32x4 v_trunc(const v_float32x4& a) +{ + __builtin_riscv_fsrm(1); + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)a.val, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), a.val, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} + +inline v_int32x4 v_round(const v_float64x2& a) +{ + __builtin_riscv_fsrm(0); + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + //_val = vset_f64m2(_val, 1, a.val); + _val = vset_f64m2(_val, 1, vfmv_v_f_f64m1(0, 2)); + vint32m1_t val = vfncvt_x_f_v_i32m1(_val, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} +inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b) +{ + __builtin_riscv_fsrm(0); + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + _val = vset_f64m2(_val, 1, b.val); + vint32m1_t val = vfncvt_x_f_v_i32m1(_val, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} +inline v_int32x4 v_floor(const v_float64x2& a) +{ + __builtin_riscv_fsrm(2); + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + vfloat32m1_t aval = vfncvt_f_f_v_f32m1(_val, 2); + + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)aval, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), aval, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} + +inline v_int32x4 v_ceil(const v_float64x2& a) +{ + __builtin_riscv_fsrm(3); + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + vfloat32m1_t aval = vfncvt_f_f_v_f32m1(_val, 2); + + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)aval, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), aval, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} + +inline v_int32x4 v_trunc(const v_float64x2& a) +{ + __builtin_riscv_fsrm(1); + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + vfloat32m1_t aval = vfncvt_f_f_v_f32m1(_val, 2); + + vint32m1_t nan = vand_vx_i32m1((vint32m1_t)aval, 0x7f800000, 4); + vbool32_t mask = vmsne_vx_i32m1_b32(nan, 0x7f800000, 4); + vint32m1_t val = vfcvt_x_f_v_i32m1_m(mask, vmv_v_x_i32m1(0, 4), aval, 4); + __builtin_riscv_fsrm(0); + return v_int32x4(val); +} + +#define OPENCV_HAL_IMPL_RISCVV_LOAD_DEINTERLEAVED(intrin, _Tpvec, num, _Tp, _T) \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec##x##num& a, v_##_Tpvec##x##num& b) \ +{ \ + v##_Tpvec##m1x2_t ret = intrin##2e_v_##_T##m1x2(ptr, num);\ + a.val = vget_##_T##m1x2_##_T##m1(ret, 0); \ + b.val = vget_##_T##m1x2_##_T##m1(ret, 1); \ +} \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec##x##num& a, v_##_Tpvec##x##num& b, v_##_Tpvec##x##num& c) \ +{ \ + v##_Tpvec##m1x3_t ret = intrin##3e_v_##_T##m1x3(ptr, num);\ + a.val = vget_##_T##m1x3_##_T##m1(ret, 0); \ + b.val = vget_##_T##m1x3_##_T##m1(ret, 1); \ + c.val = vget_##_T##m1x3_##_T##m1(ret, 2); \ +}\ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec##x##num& a, v_##_Tpvec##x##num& b, \ + v_##_Tpvec##x##num& c, v_##_Tpvec##x##num& d) \ +{ \ + v##_Tpvec##m1x4_t ret = intrin##4e_v_##_T##m1x4(ptr, num);\ + a.val = vget_##_T##m1x4_##_T##m1(ret, 0); \ + b.val = vget_##_T##m1x4_##_T##m1(ret, 1); \ + c.val = vget_##_T##m1x4_##_T##m1(ret, 2); \ + d.val = vget_##_T##m1x4_##_T##m1(ret, 3); \ +} \ + +#define OPENCV_HAL_IMPL_RISCVV_STORE_INTERLEAVED(intrin, _Tpvec, num, _Tp, _T) \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec##x##num& a, const v_##_Tpvec##x##num& b, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + v##_Tpvec##m1x2_t ret = vundefined_##_T##m1x2(); \ + ret = vset_##_T##m1x2(ret, 0, a.val); \ + ret = vset_##_T##m1x2(ret, 1, b.val); \ + intrin##2e_v_##_T##m1x2(ptr, ret, num); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec##x##num& a, const v_##_Tpvec##x##num& b, \ + const v_##_Tpvec##x##num& c, hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + v##_Tpvec##m1x3_t ret = vundefined_##_T##m1x3(); \ + ret = vset_##_T##m1x3(ret, 0, a.val); \ + ret = vset_##_T##m1x3(ret, 1, b.val); \ + ret = vset_##_T##m1x3(ret, 2, c.val); \ + intrin##3e_v_##_T##m1x3(ptr, ret, num); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec##x##num& a, const v_##_Tpvec##x##num& b, \ + const v_##_Tpvec##x##num& c, const v_##_Tpvec##x##num& d, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED ) \ +{ \ + v##_Tpvec##m1x4_t ret = vundefined_##_T##m1x4(); \ + ret = vset_##_T##m1x4(ret, 0, a.val); \ + ret = vset_##_T##m1x4(ret, 1, b.val); \ + ret = vset_##_T##m1x4(ret, 2, c.val); \ + ret = vset_##_T##m1x4(ret, 3, d.val); \ + intrin##4e_v_##_T##m1x4(ptr, ret, num); \ +} + +#define OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(_Tpvec, _Tp, num, ld, st, _T) \ +OPENCV_HAL_IMPL_RISCVV_LOAD_DEINTERLEAVED(ld, _Tpvec, num, _Tp, _T) \ +OPENCV_HAL_IMPL_RISCVV_STORE_INTERLEAVED(st, _Tpvec, num, _Tp, _T) + +//OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(uint8, uchar, ) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(int8, schar, 16, vlseg, vsseg, i8) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(int16, short, 8, vlseg, vsseg, i16) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(int32, int, 4, vlseg, vsseg, i32) + +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(uint8, unsigned char, 16, vlseg, vsseg, u8) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(uint16, unsigned short, 8, vlseg, vsseg, u16) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED(uint32, unsigned int, 4, vlseg, vsseg, u32) + +#define OPENCV_HAL_IMPL_RISCVV_INTERLEAVED_(_Tpvec, _Tp, num, _T) \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec##x##num& a, v_##_Tpvec##x##num& b) \ +{ \ + v##_Tpvec##m1x2_t ret = vlseg2e_v_##_T##m1x2(ptr, num); \ + a.val = vget_##_T##m1x2_##_T##m1(ret, 0); \ + b.val = vget_##_T##m1x2_##_T##m1(ret, 1); \ +} \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec##x##num& a, v_##_Tpvec##x##num& b, v_##_Tpvec##x##num& c) \ +{ \ + v##_Tpvec##m1x3_t ret = vlseg3e_v_##_T##m1x3(ptr, num); \ + a.val = vget_##_T##m1x3_##_T##m1(ret, 0); \ + b.val = vget_##_T##m1x3_##_T##m1(ret, 1); \ + c.val = vget_##_T##m1x3_##_T##m1(ret, 2); \ +}\ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec##x##num& a, v_##_Tpvec##x##num& b, \ + v_##_Tpvec##x##num& c, v_##_Tpvec##x##num& d) \ +{ \ + v##_Tpvec##m1x4_t ret = vlseg4e_v_##_T##m1x4(ptr, num); \ + a.val = vget_##_T##m1x4_##_T##m1(ret, 0); \ + b.val = vget_##_T##m1x4_##_T##m1(ret, 1); \ + c.val = vget_##_T##m1x4_##_T##m1(ret, 2); \ + d.val = vget_##_T##m1x4_##_T##m1(ret, 3); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec##x##num& a, const v_##_Tpvec##x##num& b, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + v##_Tpvec##m1x2_t ret = vundefined_##_T##m1x2(); \ + ret = vset_##_T##m1x2(ret, 0, a.val); \ + ret = vset_##_T##m1x2(ret, 1, b.val); \ + vsseg2e_v_##_T##m1x2(ptr, ret, num); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec##x##num& a, const v_##_Tpvec##x##num& b, \ + const v_##_Tpvec##x##num& c, hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + v##_Tpvec##m1x3_t ret = vundefined_##_T##m1x3(); \ + ret = vset_##_T##m1x3(ret, 0, a.val); \ + ret = vset_##_T##m1x3(ret, 1, b.val); \ + ret = vset_##_T##m1x3(ret, 2, c.val); \ + vsseg3e_v_##_T##m1x3(ptr, ret, num); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec##x##num& a, const v_##_Tpvec##x##num& b, \ + const v_##_Tpvec##x##num& c, const v_##_Tpvec##x##num& d, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED ) \ +{ \ + v##_Tpvec##m1x4_t ret = vundefined_##_T##m1x4(); \ + ret = vset_##_T##m1x4(ret, 0, a.val); \ + ret = vset_##_T##m1x4(ret, 1, b.val); \ + ret = vset_##_T##m1x4(ret, 2, c.val); \ + ret = vset_##_T##m1x4(ret, 3, d.val); \ + vsseg4e_v_##_T##m1x4(ptr, ret, num); \ +} +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED_(float32, float, 4, f32) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED_(float64, double, 2, f64) + +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED_(uint64, unsigned long, 2, u64) +OPENCV_HAL_IMPL_RISCVV_INTERLEAVED_(int64, long, 2, i64) + +inline v_float32x4 v_cvt_f32(const v_int32x4& a) +{ + return v_float32x4(vfcvt_f_x_v_f32m1(a.val, 4)); +} + +#if CV_SIMD128_64F +inline v_float32x4 v_cvt_f32(const v_float64x2& a) +{ + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + vfloat32m1_t aval = vfncvt_f_f_v_f32m1(_val, 2); + return v_float32x4(aval); +} + +inline v_float32x4 v_cvt_f32(const v_float64x2& a, const v_float64x2& b) +{ + vfloat64m2_t _val = vundefined_f64m2(); + _val = vset_f64m2(_val, 0, a.val); + _val = vset_f64m2(_val, 1, b.val); + vfloat32m1_t aval = vfncvt_f_f_v_f32m1(_val, 4); + return v_float32x4(aval); +} + +inline v_float64x2 v_cvt_f64(const v_int32x4& a) +{ + vfloat32m1_t val = vfcvt_f_x_v_f32m1(a.val, 4); + vfloat64m2_t _val = vfwcvt_f_f_v_f64m2(val, 4); + return v_float64x2(vget_f64m2_f64m1(_val, 0)); +} + +inline v_float64x2 v_cvt_f64_high(const v_int32x4& a) +{ + vfloat32m1_t val = vfcvt_f_x_v_f32m1(a.val, 4); + vfloat64m2_t _val = vfwcvt_f_f_v_f64m2(val, 4); + return v_float64x2(vget_f64m2_f64m1(_val, 1)); +} + +inline v_float64x2 v_cvt_f64(const v_float32x4& a) +{ + vfloat64m2_t _val = vfwcvt_f_f_v_f64m2(a.val, 4); + return v_float64x2(vget_f64m2_f64m1(_val, 0)); +} + +inline v_float64x2 v_cvt_f64_high(const v_float32x4& a) +{ + vfloat64m2_t _val = vfwcvt_f_f_v_f64m2(a.val, 4); + return v_float64x2(vget_f64m2_f64m1(_val, 1)); +} + +inline v_float64x2 v_cvt_f64(const v_int64x2& a) +{ + return v_float64x2(vfcvt_f_x_v_f64m1(a.val, 2)); +} + +#endif +inline v_int8x16 v_interleave_pairs(const v_int8x16& vec) +{ + vuint64m1_t m0 = {0x0705060403010200, 0x0F0D0E0C0B090A08}; + return v_int8x16(vrgather_vv_i8m1(vec.val, (vuint8m1_t)m0, 16)); +} +inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec) +{ + return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); +} + +inline v_int8x16 v_interleave_quads(const v_int8x16& vec) +{ + vuint64m1_t m0 = {0x0703060205010400, 0x0F0B0E0A0D090C08}; + return v_int8x16(vrgather_vv_i8m1(vec.val, (vuint8m1_t)m0, 16)); +} +inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec) +{ + return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); +} + +inline v_int16x8 v_interleave_pairs(const v_int16x8& vec) +{ + vuint64m1_t m0 = {0x0706030205040100, 0x0F0E0B0A0D0C0908}; + return v_int16x8((vint16m1_t)vrgather_vv_u8m1((vuint8m1_t)vec.val, (vuint8m1_t)m0, 16)); +} +inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); } +inline v_int16x8 v_interleave_quads(const v_int16x8& vec) +{ + vuint64m1_t m0 = {0x0B0A030209080100, 0x0F0E07060D0C0504}; + return v_int16x8((vint16m1_t)vrgather_vv_u8m1((vuint8m1_t)(vec.val), (vuint8m1_t)m0, 16)); +} +inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_interleave_pairs(const v_int32x4& vec) +{ + vuint64m1_t m0 = {0x0B0A090803020100, 0x0F0E0D0C07060504}; + return v_int32x4((vint32m1_t)vrgather_vv_u8m1((vuint8m1_t)(vec.val), (vuint8m1_t)m0, 16)); +} +inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_float32x4 v_interleave_pairs(const v_float32x4& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_int8x16 v_pack_triplets(const v_int8x16& vec) +{ + vuint64m1_t m0 = {0x0908060504020100, 0xFFFFFFFF0E0D0C0A}; + return v_int8x16((vint8m1_t)vrgather_vv_u8m1((vuint8m1_t)(vec.val), (vuint8m1_t)m0, 16)); +} +inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_pack_triplets(const v_int16x8& vec) +{ + vuint64m1_t m0 = {0x0908050403020100, 0xFFFFFFFF0D0C0B0A}; + return v_int16x8((vint16m1_t)vrgather_vv_u8m1((vuint8m1_t)(vec.val), (vuint8m1_t)m0, 16)); +} +inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; } +inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; } +inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; } + +#if CV_SIMD128_64F +inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b) +{ return v_cvt_f64(v_dotprod(a, b)); } +inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b, + const v_float64x2& c) +{ return v_dotprod_expand(a, b) + c; } +inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b) +{ + vint64m2_t v1 = vwmul_vv_i64m2(a.val, b.val, 4); + vfloat64m1_t res = vfcvt_f_x_v_f64m1(vadd_vv_i64m1(vget_i64m2_i64m1(v1, 0), vget_i64m2_i64m1(v1, 1), 2), 2); + return v_float64x2(res); +} +inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b, const v_float64x2& c) +{ v_float64x2 res = v_dotprod_expand_fast(a, b); + return res + c; } +#endif +////// FP16 support /////// +inline v_float32x4 v_load_expand(const float16_t* ptr) +{ + vfloat16m1_t v = vle_v_f16m1((__fp16*)ptr, 4); + vfloat32m2_t v32 = vfwcvt_f_f_v_f32m2(v, 4); + return v_float32x4(vget_f32m2_f32m1(v32, 0)); +} + +inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +{ + vfloat32m2_t v32 = vundefined_f32m2(); + v32 = vset_f32m2(v32, 0, v.val); + vfloat16m1_t hv = vfncvt_f_f_v_f16m1(v32, 4); + vse_v_f16m1((__fp16*)ptr, hv, 4); +} + + +inline void v_cleanup() {} + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} +#endif diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index eeb83c074475..6768be76834b 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -2451,7 +2451,8 @@ class CV_EXPORTS UMat //! <0 - a diagonal from the lower half) UMat diag(int d=0) const; //! constructs a square diagonal matrix which main diagonal is vector "d" - static UMat diag(const UMat& d); + static UMat diag(const UMat& d, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat diag(const UMat& d) { return diag(d, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload //! returns deep copy of the matrix, i.e. the data is copied UMat clone() const CV_NODISCARD; @@ -2485,14 +2486,22 @@ class CV_EXPORTS UMat double dot(InputArray m) const; //! Matlab-style matrix initialization - static UMat zeros(int rows, int cols, int type); - static UMat zeros(Size size, int type); - static UMat zeros(int ndims, const int* sz, int type); - static UMat ones(int rows, int cols, int type); - static UMat ones(Size size, int type); - static UMat ones(int ndims, const int* sz, int type); - static UMat eye(int rows, int cols, int type); - static UMat eye(Size size, int type); + static UMat zeros(int rows, int cols, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat zeros(Size size, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat zeros(int rows, int cols, int type) { return zeros(rows, cols, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat zeros(Size size, int type) { return zeros(size, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat zeros(int ndims, const int* sz, int type) { return zeros(ndims, sz, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat ones(int rows, int cols, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat ones(Size size, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat ones(int rows, int cols, int type) { return ones(rows, cols, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat ones(Size size, int type) { return ones(size, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat ones(int ndims, const int* sz, int type) { return ones(ndims, sz, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat eye(int rows, int cols, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat eye(Size size, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/); + static UMat eye(int rows, int cols, int type) { return eye(rows, cols, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload + static UMat eye(Size size, int type) { return eye(size, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload //! allocates new matrix data unless the matrix already has specified size and type. // previous data is unreferenced if needed. @@ -2572,27 +2581,38 @@ class CV_EXPORTS UMat - number of channels */ int flags; + //! the matrix dimensionality, >= 2 int dims; - //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions - int rows, cols; + + //! number of rows in the matrix; -1 when the matrix has more than 2 dimensions + int rows; + + //! number of columns in the matrix; -1 when the matrix has more than 2 dimensions + int cols; //! custom allocator MatAllocator* allocator; - UMatUsageFlags usageFlags; // usage flags for allocator + + //! usage flags for allocator; recommend do not set directly, instead set during construct/create/getUMat + UMatUsageFlags usageFlags; + //! and the standard allocator static MatAllocator* getStdAllocator(); //! internal use method: updates the continuity flag void updateContinuityFlag(); - // black-box container of UMat data + //! black-box container of UMat data UMatData* u; - // offset of the submatrix (or 0) + //! offset of the submatrix (or 0) size_t offset; + //! dimensional size of the matrix; accessible in various formats MatSize size; + + //! number of bytes each matrix element/row/plane/dimension occupies MatStep step; protected: diff --git a/modules/core/include/opencv2/core/opencl/opencl_info.hpp b/modules/core/include/opencv2/core/opencl/opencl_info.hpp index 5e5c846ad059..3ead76e5c46e 100644 --- a/modules/core/include/opencv2/core/opencl/opencl_info.hpp +++ b/modules/core/include/opencv2/core/opencl/opencl_info.hpp @@ -144,6 +144,10 @@ static void dumpOpenCLInformation() DUMP_MESSAGE_STDOUT(" Double support = " << doubleSupportStr); DUMP_CONFIG_PROPERTY("cv_ocl_current_haveDoubleSupport", device.doubleFPConfig() > 0); + const char* halfSupportStr = device.halfFPConfig() > 0 ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Half support = " << halfSupportStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_haveHalfSupport", device.halfFPConfig() > 0); + const char* isUnifiedMemoryStr = device.hostUnifiedMemory() ? "Yes" : "No"; DUMP_MESSAGE_STDOUT(" Host unified memory = " << isUnifiedMemoryStr); DUMP_CONFIG_PROPERTY("cv_ocl_current_hostUnifiedMemory", device.hostUnifiedMemory()); @@ -191,6 +195,9 @@ static void dumpOpenCLInformation() DUMP_MESSAGE_STDOUT(" Preferred vector width double = " << device.preferredVectorWidthDouble()); DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthDouble", device.preferredVectorWidthDouble()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width half = " << device.preferredVectorWidthHalf()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthHalf", device.preferredVectorWidthHalf()); } catch (...) { diff --git a/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp b/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp deleted file mode 100644 index 65c84935240d..000000000000 --- a/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp +++ /dev/null @@ -1,714 +0,0 @@ -// -// AUTOGENERATED, DO NOT EDIT -// -#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDBLAS_HPP -#error "Invalid usage" -#endif - -// generated by parser_clamdblas.py -#define clAmdBlasAddScratchImage clAmdBlasAddScratchImage_ -#define clAmdBlasCaxpy clAmdBlasCaxpy_ -#define clAmdBlasCcopy clAmdBlasCcopy_ -#define clAmdBlasCdotc clAmdBlasCdotc_ -#define clAmdBlasCdotu clAmdBlasCdotu_ -#define clAmdBlasCgbmv clAmdBlasCgbmv_ -#define clAmdBlasCgemm clAmdBlasCgemm_ -#define clAmdBlasCgemmEx clAmdBlasCgemmEx_ -#define clAmdBlasCgemv clAmdBlasCgemv_ -#define clAmdBlasCgemvEx clAmdBlasCgemvEx_ -#define clAmdBlasCgerc clAmdBlasCgerc_ -#define clAmdBlasCgeru clAmdBlasCgeru_ -#define clAmdBlasChbmv clAmdBlasChbmv_ -#define clAmdBlasChemm clAmdBlasChemm_ -#define clAmdBlasChemv clAmdBlasChemv_ -#define clAmdBlasCher clAmdBlasCher_ -#define clAmdBlasCher2 clAmdBlasCher2_ -#define clAmdBlasCher2k clAmdBlasCher2k_ -#define clAmdBlasCherk clAmdBlasCherk_ -#define clAmdBlasChpmv clAmdBlasChpmv_ -#define clAmdBlasChpr clAmdBlasChpr_ -#define clAmdBlasChpr2 clAmdBlasChpr2_ -#define clAmdBlasCrotg clAmdBlasCrotg_ -#define clAmdBlasCscal clAmdBlasCscal_ -#define clAmdBlasCsrot clAmdBlasCsrot_ -#define clAmdBlasCsscal clAmdBlasCsscal_ -#define clAmdBlasCswap clAmdBlasCswap_ -#define clAmdBlasCsymm clAmdBlasCsymm_ -#define clAmdBlasCsyr2k clAmdBlasCsyr2k_ -#define clAmdBlasCsyr2kEx clAmdBlasCsyr2kEx_ -#define clAmdBlasCsyrk clAmdBlasCsyrk_ -#define clAmdBlasCsyrkEx clAmdBlasCsyrkEx_ -#define clAmdBlasCtbmv clAmdBlasCtbmv_ -#define clAmdBlasCtbsv clAmdBlasCtbsv_ -#define clAmdBlasCtpmv clAmdBlasCtpmv_ -#define clAmdBlasCtpsv clAmdBlasCtpsv_ -#define clAmdBlasCtrmm clAmdBlasCtrmm_ -#define clAmdBlasCtrmmEx clAmdBlasCtrmmEx_ -#define clAmdBlasCtrmv clAmdBlasCtrmv_ -#define clAmdBlasCtrsm clAmdBlasCtrsm_ -#define clAmdBlasCtrsmEx clAmdBlasCtrsmEx_ -#define clAmdBlasCtrsv clAmdBlasCtrsv_ -#define clAmdBlasDasum clAmdBlasDasum_ -#define clAmdBlasDaxpy clAmdBlasDaxpy_ -#define clAmdBlasDcopy clAmdBlasDcopy_ -#define clAmdBlasDdot clAmdBlasDdot_ -#define clAmdBlasDgbmv clAmdBlasDgbmv_ -#define clAmdBlasDgemm clAmdBlasDgemm_ -#define clAmdBlasDgemmEx clAmdBlasDgemmEx_ -#define clAmdBlasDgemv clAmdBlasDgemv_ -#define clAmdBlasDgemvEx clAmdBlasDgemvEx_ -#define clAmdBlasDger clAmdBlasDger_ -#define clAmdBlasDnrm2 clAmdBlasDnrm2_ -#define clAmdBlasDrot clAmdBlasDrot_ -#define clAmdBlasDrotg clAmdBlasDrotg_ -#define clAmdBlasDrotm clAmdBlasDrotm_ -#define clAmdBlasDrotmg clAmdBlasDrotmg_ -#define clAmdBlasDsbmv clAmdBlasDsbmv_ -#define clAmdBlasDscal clAmdBlasDscal_ -#define clAmdBlasDspmv clAmdBlasDspmv_ -#define clAmdBlasDspr clAmdBlasDspr_ -#define clAmdBlasDspr2 clAmdBlasDspr2_ -#define clAmdBlasDswap clAmdBlasDswap_ -#define clAmdBlasDsymm clAmdBlasDsymm_ -#define clAmdBlasDsymv clAmdBlasDsymv_ -#define clAmdBlasDsymvEx clAmdBlasDsymvEx_ -#define clAmdBlasDsyr clAmdBlasDsyr_ -#define clAmdBlasDsyr2 clAmdBlasDsyr2_ -#define clAmdBlasDsyr2k clAmdBlasDsyr2k_ -#define clAmdBlasDsyr2kEx clAmdBlasDsyr2kEx_ -#define clAmdBlasDsyrk clAmdBlasDsyrk_ -#define clAmdBlasDsyrkEx clAmdBlasDsyrkEx_ -#define clAmdBlasDtbmv clAmdBlasDtbmv_ -#define clAmdBlasDtbsv clAmdBlasDtbsv_ -#define clAmdBlasDtpmv clAmdBlasDtpmv_ -#define clAmdBlasDtpsv clAmdBlasDtpsv_ -#define clAmdBlasDtrmm clAmdBlasDtrmm_ -#define clAmdBlasDtrmmEx clAmdBlasDtrmmEx_ -#define clAmdBlasDtrmv clAmdBlasDtrmv_ -#define clAmdBlasDtrsm clAmdBlasDtrsm_ -#define clAmdBlasDtrsmEx clAmdBlasDtrsmEx_ -#define clAmdBlasDtrsv clAmdBlasDtrsv_ -#define clAmdBlasDzasum clAmdBlasDzasum_ -#define clAmdBlasDznrm2 clAmdBlasDznrm2_ -#define clAmdBlasGetVersion clAmdBlasGetVersion_ -#define clAmdBlasRemoveScratchImage clAmdBlasRemoveScratchImage_ -#define clAmdBlasSasum clAmdBlasSasum_ -#define clAmdBlasSaxpy clAmdBlasSaxpy_ -#define clAmdBlasScasum clAmdBlasScasum_ -#define clAmdBlasScnrm2 clAmdBlasScnrm2_ -#define clAmdBlasScopy clAmdBlasScopy_ -#define clAmdBlasSdot clAmdBlasSdot_ -#define clAmdBlasSetup clAmdBlasSetup_ -#define clAmdBlasSgbmv clAmdBlasSgbmv_ -#define clAmdBlasSgemm clAmdBlasSgemm_ -#define clAmdBlasSgemmEx clAmdBlasSgemmEx_ -#define clAmdBlasSgemv clAmdBlasSgemv_ -#define clAmdBlasSgemvEx clAmdBlasSgemvEx_ -#define clAmdBlasSger clAmdBlasSger_ -#define clAmdBlasSnrm2 clAmdBlasSnrm2_ -#define clAmdBlasSrot clAmdBlasSrot_ -#define clAmdBlasSrotg clAmdBlasSrotg_ -#define clAmdBlasSrotm clAmdBlasSrotm_ -#define clAmdBlasSrotmg clAmdBlasSrotmg_ -#define clAmdBlasSsbmv clAmdBlasSsbmv_ -#define clAmdBlasSscal clAmdBlasSscal_ -#define clAmdBlasSspmv clAmdBlasSspmv_ -#define clAmdBlasSspr clAmdBlasSspr_ -#define clAmdBlasSspr2 clAmdBlasSspr2_ -#define clAmdBlasSswap clAmdBlasSswap_ -#define clAmdBlasSsymm clAmdBlasSsymm_ -#define clAmdBlasSsymv clAmdBlasSsymv_ -#define clAmdBlasSsymvEx clAmdBlasSsymvEx_ -#define clAmdBlasSsyr clAmdBlasSsyr_ -#define clAmdBlasSsyr2 clAmdBlasSsyr2_ -#define clAmdBlasSsyr2k clAmdBlasSsyr2k_ -#define clAmdBlasSsyr2kEx clAmdBlasSsyr2kEx_ -#define clAmdBlasSsyrk clAmdBlasSsyrk_ -#define clAmdBlasSsyrkEx clAmdBlasSsyrkEx_ -#define clAmdBlasStbmv clAmdBlasStbmv_ -#define clAmdBlasStbsv clAmdBlasStbsv_ -#define clAmdBlasStpmv clAmdBlasStpmv_ -#define clAmdBlasStpsv clAmdBlasStpsv_ -#define clAmdBlasStrmm clAmdBlasStrmm_ -#define clAmdBlasStrmmEx clAmdBlasStrmmEx_ -#define clAmdBlasStrmv clAmdBlasStrmv_ -#define clAmdBlasStrsm clAmdBlasStrsm_ -#define clAmdBlasStrsmEx clAmdBlasStrsmEx_ -#define clAmdBlasStrsv clAmdBlasStrsv_ -#define clAmdBlasTeardown clAmdBlasTeardown_ -#define clAmdBlasZaxpy clAmdBlasZaxpy_ -#define clAmdBlasZcopy clAmdBlasZcopy_ -#define clAmdBlasZdotc clAmdBlasZdotc_ -#define clAmdBlasZdotu clAmdBlasZdotu_ -#define clAmdBlasZdrot clAmdBlasZdrot_ -#define clAmdBlasZdscal clAmdBlasZdscal_ -#define clAmdBlasZgbmv clAmdBlasZgbmv_ -#define clAmdBlasZgemm clAmdBlasZgemm_ -#define clAmdBlasZgemmEx clAmdBlasZgemmEx_ -#define clAmdBlasZgemv clAmdBlasZgemv_ -#define clAmdBlasZgemvEx clAmdBlasZgemvEx_ -#define clAmdBlasZgerc clAmdBlasZgerc_ -#define clAmdBlasZgeru clAmdBlasZgeru_ -#define clAmdBlasZhbmv clAmdBlasZhbmv_ -#define clAmdBlasZhemm clAmdBlasZhemm_ -#define clAmdBlasZhemv clAmdBlasZhemv_ -#define clAmdBlasZher clAmdBlasZher_ -#define clAmdBlasZher2 clAmdBlasZher2_ -#define clAmdBlasZher2k clAmdBlasZher2k_ -#define clAmdBlasZherk clAmdBlasZherk_ -#define clAmdBlasZhpmv clAmdBlasZhpmv_ -#define clAmdBlasZhpr clAmdBlasZhpr_ -#define clAmdBlasZhpr2 clAmdBlasZhpr2_ -#define clAmdBlasZrotg clAmdBlasZrotg_ -#define clAmdBlasZscal clAmdBlasZscal_ -#define clAmdBlasZswap clAmdBlasZswap_ -#define clAmdBlasZsymm clAmdBlasZsymm_ -#define clAmdBlasZsyr2k clAmdBlasZsyr2k_ -#define clAmdBlasZsyr2kEx clAmdBlasZsyr2kEx_ -#define clAmdBlasZsyrk clAmdBlasZsyrk_ -#define clAmdBlasZsyrkEx clAmdBlasZsyrkEx_ -#define clAmdBlasZtbmv clAmdBlasZtbmv_ -#define clAmdBlasZtbsv clAmdBlasZtbsv_ -#define clAmdBlasZtpmv clAmdBlasZtpmv_ -#define clAmdBlasZtpsv clAmdBlasZtpsv_ -#define clAmdBlasZtrmm clAmdBlasZtrmm_ -#define clAmdBlasZtrmmEx clAmdBlasZtrmmEx_ -#define clAmdBlasZtrmv clAmdBlasZtrmv_ -#define clAmdBlasZtrsm clAmdBlasZtrsm_ -#define clAmdBlasZtrsmEx clAmdBlasZtrsmEx_ -#define clAmdBlasZtrsv clAmdBlasZtrsv_ -#define clAmdBlasiCamax clAmdBlasiCamax_ -#define clAmdBlasiDamax clAmdBlasiDamax_ -#define clAmdBlasiSamax clAmdBlasiSamax_ -#define clAmdBlasiZamax clAmdBlasiZamax_ - -#include - -// generated by parser_clamdblas.py -#undef clAmdBlasAddScratchImage -//#define clAmdBlasAddScratchImage clAmdBlasAddScratchImage_pfn -#undef clAmdBlasCaxpy -//#define clAmdBlasCaxpy clAmdBlasCaxpy_pfn -#undef clAmdBlasCcopy -//#define clAmdBlasCcopy clAmdBlasCcopy_pfn -#undef clAmdBlasCdotc -//#define clAmdBlasCdotc clAmdBlasCdotc_pfn -#undef clAmdBlasCdotu -//#define clAmdBlasCdotu clAmdBlasCdotu_pfn -#undef clAmdBlasCgbmv -//#define clAmdBlasCgbmv clAmdBlasCgbmv_pfn -#undef clAmdBlasCgemm -//#define clAmdBlasCgemm clAmdBlasCgemm_pfn -#undef clAmdBlasCgemmEx -#define clAmdBlasCgemmEx clAmdBlasCgemmEx_pfn -#undef clAmdBlasCgemv -//#define clAmdBlasCgemv clAmdBlasCgemv_pfn -#undef clAmdBlasCgemvEx -//#define clAmdBlasCgemvEx clAmdBlasCgemvEx_pfn -#undef clAmdBlasCgerc -//#define clAmdBlasCgerc clAmdBlasCgerc_pfn -#undef clAmdBlasCgeru -//#define clAmdBlasCgeru clAmdBlasCgeru_pfn -#undef clAmdBlasChbmv -//#define clAmdBlasChbmv clAmdBlasChbmv_pfn -#undef clAmdBlasChemm -//#define clAmdBlasChemm clAmdBlasChemm_pfn -#undef clAmdBlasChemv -//#define clAmdBlasChemv clAmdBlasChemv_pfn -#undef clAmdBlasCher -//#define clAmdBlasCher clAmdBlasCher_pfn -#undef clAmdBlasCher2 -//#define clAmdBlasCher2 clAmdBlasCher2_pfn -#undef clAmdBlasCher2k -//#define clAmdBlasCher2k clAmdBlasCher2k_pfn -#undef clAmdBlasCherk -//#define clAmdBlasCherk clAmdBlasCherk_pfn -#undef clAmdBlasChpmv -//#define clAmdBlasChpmv clAmdBlasChpmv_pfn -#undef clAmdBlasChpr -//#define clAmdBlasChpr clAmdBlasChpr_pfn -#undef clAmdBlasChpr2 -//#define clAmdBlasChpr2 clAmdBlasChpr2_pfn -#undef clAmdBlasCrotg -//#define clAmdBlasCrotg clAmdBlasCrotg_pfn -#undef clAmdBlasCscal -//#define clAmdBlasCscal clAmdBlasCscal_pfn -#undef clAmdBlasCsrot -//#define clAmdBlasCsrot clAmdBlasCsrot_pfn -#undef clAmdBlasCsscal -//#define clAmdBlasCsscal clAmdBlasCsscal_pfn -#undef clAmdBlasCswap -//#define clAmdBlasCswap clAmdBlasCswap_pfn -#undef clAmdBlasCsymm -//#define clAmdBlasCsymm clAmdBlasCsymm_pfn -#undef clAmdBlasCsyr2k -//#define clAmdBlasCsyr2k clAmdBlasCsyr2k_pfn -#undef clAmdBlasCsyr2kEx -//#define clAmdBlasCsyr2kEx clAmdBlasCsyr2kEx_pfn -#undef clAmdBlasCsyrk -//#define clAmdBlasCsyrk clAmdBlasCsyrk_pfn -#undef clAmdBlasCsyrkEx -//#define clAmdBlasCsyrkEx clAmdBlasCsyrkEx_pfn -#undef clAmdBlasCtbmv -//#define clAmdBlasCtbmv clAmdBlasCtbmv_pfn -#undef clAmdBlasCtbsv -//#define clAmdBlasCtbsv clAmdBlasCtbsv_pfn -#undef clAmdBlasCtpmv -//#define clAmdBlasCtpmv clAmdBlasCtpmv_pfn -#undef clAmdBlasCtpsv -//#define clAmdBlasCtpsv clAmdBlasCtpsv_pfn -#undef clAmdBlasCtrmm -//#define clAmdBlasCtrmm clAmdBlasCtrmm_pfn -#undef clAmdBlasCtrmmEx -//#define clAmdBlasCtrmmEx clAmdBlasCtrmmEx_pfn -#undef clAmdBlasCtrmv -//#define clAmdBlasCtrmv clAmdBlasCtrmv_pfn -#undef clAmdBlasCtrsm -//#define clAmdBlasCtrsm clAmdBlasCtrsm_pfn -#undef clAmdBlasCtrsmEx -//#define clAmdBlasCtrsmEx clAmdBlasCtrsmEx_pfn -#undef clAmdBlasCtrsv -//#define clAmdBlasCtrsv clAmdBlasCtrsv_pfn -#undef clAmdBlasDasum -//#define clAmdBlasDasum clAmdBlasDasum_pfn -#undef clAmdBlasDaxpy -//#define clAmdBlasDaxpy clAmdBlasDaxpy_pfn -#undef clAmdBlasDcopy -//#define clAmdBlasDcopy clAmdBlasDcopy_pfn -#undef clAmdBlasDdot -//#define clAmdBlasDdot clAmdBlasDdot_pfn -#undef clAmdBlasDgbmv -//#define clAmdBlasDgbmv clAmdBlasDgbmv_pfn -#undef clAmdBlasDgemm -//#define clAmdBlasDgemm clAmdBlasDgemm_pfn -#undef clAmdBlasDgemmEx -#define clAmdBlasDgemmEx clAmdBlasDgemmEx_pfn -#undef clAmdBlasDgemv -//#define clAmdBlasDgemv clAmdBlasDgemv_pfn -#undef clAmdBlasDgemvEx -//#define clAmdBlasDgemvEx clAmdBlasDgemvEx_pfn -#undef clAmdBlasDger -//#define clAmdBlasDger clAmdBlasDger_pfn -#undef clAmdBlasDnrm2 -//#define clAmdBlasDnrm2 clAmdBlasDnrm2_pfn -#undef clAmdBlasDrot -//#define clAmdBlasDrot clAmdBlasDrot_pfn -#undef clAmdBlasDrotg -//#define clAmdBlasDrotg clAmdBlasDrotg_pfn -#undef clAmdBlasDrotm -//#define clAmdBlasDrotm clAmdBlasDrotm_pfn -#undef clAmdBlasDrotmg -//#define clAmdBlasDrotmg clAmdBlasDrotmg_pfn -#undef clAmdBlasDsbmv -//#define clAmdBlasDsbmv clAmdBlasDsbmv_pfn -#undef clAmdBlasDscal -//#define clAmdBlasDscal clAmdBlasDscal_pfn -#undef clAmdBlasDspmv -//#define clAmdBlasDspmv clAmdBlasDspmv_pfn -#undef clAmdBlasDspr -//#define clAmdBlasDspr clAmdBlasDspr_pfn -#undef clAmdBlasDspr2 -//#define clAmdBlasDspr2 clAmdBlasDspr2_pfn -#undef clAmdBlasDswap -//#define clAmdBlasDswap clAmdBlasDswap_pfn -#undef clAmdBlasDsymm -//#define clAmdBlasDsymm clAmdBlasDsymm_pfn -#undef clAmdBlasDsymv -//#define clAmdBlasDsymv clAmdBlasDsymv_pfn -#undef clAmdBlasDsymvEx -//#define clAmdBlasDsymvEx clAmdBlasDsymvEx_pfn -#undef clAmdBlasDsyr -//#define clAmdBlasDsyr clAmdBlasDsyr_pfn -#undef clAmdBlasDsyr2 -//#define clAmdBlasDsyr2 clAmdBlasDsyr2_pfn -#undef clAmdBlasDsyr2k -//#define clAmdBlasDsyr2k clAmdBlasDsyr2k_pfn -#undef clAmdBlasDsyr2kEx -//#define clAmdBlasDsyr2kEx clAmdBlasDsyr2kEx_pfn -#undef clAmdBlasDsyrk -//#define clAmdBlasDsyrk clAmdBlasDsyrk_pfn -#undef clAmdBlasDsyrkEx -//#define clAmdBlasDsyrkEx clAmdBlasDsyrkEx_pfn -#undef clAmdBlasDtbmv -//#define clAmdBlasDtbmv clAmdBlasDtbmv_pfn -#undef clAmdBlasDtbsv -//#define clAmdBlasDtbsv clAmdBlasDtbsv_pfn -#undef clAmdBlasDtpmv -//#define clAmdBlasDtpmv clAmdBlasDtpmv_pfn -#undef clAmdBlasDtpsv -//#define clAmdBlasDtpsv clAmdBlasDtpsv_pfn -#undef clAmdBlasDtrmm -//#define clAmdBlasDtrmm clAmdBlasDtrmm_pfn -#undef clAmdBlasDtrmmEx -//#define clAmdBlasDtrmmEx clAmdBlasDtrmmEx_pfn -#undef clAmdBlasDtrmv -//#define clAmdBlasDtrmv clAmdBlasDtrmv_pfn -#undef clAmdBlasDtrsm -//#define clAmdBlasDtrsm clAmdBlasDtrsm_pfn -#undef clAmdBlasDtrsmEx -//#define clAmdBlasDtrsmEx clAmdBlasDtrsmEx_pfn -#undef clAmdBlasDtrsv -//#define clAmdBlasDtrsv clAmdBlasDtrsv_pfn -#undef clAmdBlasDzasum -//#define clAmdBlasDzasum clAmdBlasDzasum_pfn -#undef clAmdBlasDznrm2 -//#define clAmdBlasDznrm2 clAmdBlasDznrm2_pfn -#undef clAmdBlasGetVersion -//#define clAmdBlasGetVersion clAmdBlasGetVersion_pfn -#undef clAmdBlasRemoveScratchImage -//#define clAmdBlasRemoveScratchImage clAmdBlasRemoveScratchImage_pfn -#undef clAmdBlasSasum -//#define clAmdBlasSasum clAmdBlasSasum_pfn -#undef clAmdBlasSaxpy -//#define clAmdBlasSaxpy clAmdBlasSaxpy_pfn -#undef clAmdBlasScasum -//#define clAmdBlasScasum clAmdBlasScasum_pfn -#undef clAmdBlasScnrm2 -//#define clAmdBlasScnrm2 clAmdBlasScnrm2_pfn -#undef clAmdBlasScopy -//#define clAmdBlasScopy clAmdBlasScopy_pfn -#undef clAmdBlasSdot -//#define clAmdBlasSdot clAmdBlasSdot_pfn -#undef clAmdBlasSetup -#define clAmdBlasSetup clAmdBlasSetup_pfn -#undef clAmdBlasSgbmv -//#define clAmdBlasSgbmv clAmdBlasSgbmv_pfn -#undef clAmdBlasSgemm -//#define clAmdBlasSgemm clAmdBlasSgemm_pfn -#undef clAmdBlasSgemmEx -#define clAmdBlasSgemmEx clAmdBlasSgemmEx_pfn -#undef clAmdBlasSgemv -//#define clAmdBlasSgemv clAmdBlasSgemv_pfn -#undef clAmdBlasSgemvEx -//#define clAmdBlasSgemvEx clAmdBlasSgemvEx_pfn -#undef clAmdBlasSger -//#define clAmdBlasSger clAmdBlasSger_pfn -#undef clAmdBlasSnrm2 -//#define clAmdBlasSnrm2 clAmdBlasSnrm2_pfn -#undef clAmdBlasSrot -//#define clAmdBlasSrot clAmdBlasSrot_pfn -#undef clAmdBlasSrotg -//#define clAmdBlasSrotg clAmdBlasSrotg_pfn -#undef clAmdBlasSrotm -//#define clAmdBlasSrotm clAmdBlasSrotm_pfn -#undef clAmdBlasSrotmg -//#define clAmdBlasSrotmg clAmdBlasSrotmg_pfn -#undef clAmdBlasSsbmv -//#define clAmdBlasSsbmv clAmdBlasSsbmv_pfn -#undef clAmdBlasSscal -//#define clAmdBlasSscal clAmdBlasSscal_pfn -#undef clAmdBlasSspmv -//#define clAmdBlasSspmv clAmdBlasSspmv_pfn -#undef clAmdBlasSspr -//#define clAmdBlasSspr clAmdBlasSspr_pfn -#undef clAmdBlasSspr2 -//#define clAmdBlasSspr2 clAmdBlasSspr2_pfn -#undef clAmdBlasSswap -//#define clAmdBlasSswap clAmdBlasSswap_pfn -#undef clAmdBlasSsymm -//#define clAmdBlasSsymm clAmdBlasSsymm_pfn -#undef clAmdBlasSsymv -//#define clAmdBlasSsymv clAmdBlasSsymv_pfn -#undef clAmdBlasSsymvEx -//#define clAmdBlasSsymvEx clAmdBlasSsymvEx_pfn -#undef clAmdBlasSsyr -//#define clAmdBlasSsyr clAmdBlasSsyr_pfn -#undef clAmdBlasSsyr2 -//#define clAmdBlasSsyr2 clAmdBlasSsyr2_pfn -#undef clAmdBlasSsyr2k -//#define clAmdBlasSsyr2k clAmdBlasSsyr2k_pfn -#undef clAmdBlasSsyr2kEx -//#define clAmdBlasSsyr2kEx clAmdBlasSsyr2kEx_pfn -#undef clAmdBlasSsyrk -//#define clAmdBlasSsyrk clAmdBlasSsyrk_pfn -#undef clAmdBlasSsyrkEx -//#define clAmdBlasSsyrkEx clAmdBlasSsyrkEx_pfn -#undef clAmdBlasStbmv -//#define clAmdBlasStbmv clAmdBlasStbmv_pfn -#undef clAmdBlasStbsv -//#define clAmdBlasStbsv clAmdBlasStbsv_pfn -#undef clAmdBlasStpmv -//#define clAmdBlasStpmv clAmdBlasStpmv_pfn -#undef clAmdBlasStpsv -//#define clAmdBlasStpsv clAmdBlasStpsv_pfn -#undef clAmdBlasStrmm -//#define clAmdBlasStrmm clAmdBlasStrmm_pfn -#undef clAmdBlasStrmmEx -//#define clAmdBlasStrmmEx clAmdBlasStrmmEx_pfn -#undef clAmdBlasStrmv -//#define clAmdBlasStrmv clAmdBlasStrmv_pfn -#undef clAmdBlasStrsm -//#define clAmdBlasStrsm clAmdBlasStrsm_pfn -#undef clAmdBlasStrsmEx -//#define clAmdBlasStrsmEx clAmdBlasStrsmEx_pfn -#undef clAmdBlasStrsv -//#define clAmdBlasStrsv clAmdBlasStrsv_pfn -#undef clAmdBlasTeardown -#define clAmdBlasTeardown clAmdBlasTeardown_pfn -#undef clAmdBlasZaxpy -//#define clAmdBlasZaxpy clAmdBlasZaxpy_pfn -#undef clAmdBlasZcopy -//#define clAmdBlasZcopy clAmdBlasZcopy_pfn -#undef clAmdBlasZdotc -//#define clAmdBlasZdotc clAmdBlasZdotc_pfn -#undef clAmdBlasZdotu -//#define clAmdBlasZdotu clAmdBlasZdotu_pfn -#undef clAmdBlasZdrot -//#define clAmdBlasZdrot clAmdBlasZdrot_pfn -#undef clAmdBlasZdscal -//#define clAmdBlasZdscal clAmdBlasZdscal_pfn -#undef clAmdBlasZgbmv -//#define clAmdBlasZgbmv clAmdBlasZgbmv_pfn -#undef clAmdBlasZgemm -//#define clAmdBlasZgemm clAmdBlasZgemm_pfn -#undef clAmdBlasZgemmEx -#define clAmdBlasZgemmEx clAmdBlasZgemmEx_pfn -#undef clAmdBlasZgemv -//#define clAmdBlasZgemv clAmdBlasZgemv_pfn -#undef clAmdBlasZgemvEx -//#define clAmdBlasZgemvEx clAmdBlasZgemvEx_pfn -#undef clAmdBlasZgerc -//#define clAmdBlasZgerc clAmdBlasZgerc_pfn -#undef clAmdBlasZgeru -//#define clAmdBlasZgeru clAmdBlasZgeru_pfn -#undef clAmdBlasZhbmv -//#define clAmdBlasZhbmv clAmdBlasZhbmv_pfn -#undef clAmdBlasZhemm -//#define clAmdBlasZhemm clAmdBlasZhemm_pfn -#undef clAmdBlasZhemv -//#define clAmdBlasZhemv clAmdBlasZhemv_pfn -#undef clAmdBlasZher -//#define clAmdBlasZher clAmdBlasZher_pfn -#undef clAmdBlasZher2 -//#define clAmdBlasZher2 clAmdBlasZher2_pfn -#undef clAmdBlasZher2k -//#define clAmdBlasZher2k clAmdBlasZher2k_pfn -#undef clAmdBlasZherk -//#define clAmdBlasZherk clAmdBlasZherk_pfn -#undef clAmdBlasZhpmv -//#define clAmdBlasZhpmv clAmdBlasZhpmv_pfn -#undef clAmdBlasZhpr -//#define clAmdBlasZhpr clAmdBlasZhpr_pfn -#undef clAmdBlasZhpr2 -//#define clAmdBlasZhpr2 clAmdBlasZhpr2_pfn -#undef clAmdBlasZrotg -//#define clAmdBlasZrotg clAmdBlasZrotg_pfn -#undef clAmdBlasZscal -//#define clAmdBlasZscal clAmdBlasZscal_pfn -#undef clAmdBlasZswap -//#define clAmdBlasZswap clAmdBlasZswap_pfn -#undef clAmdBlasZsymm -//#define clAmdBlasZsymm clAmdBlasZsymm_pfn -#undef clAmdBlasZsyr2k -//#define clAmdBlasZsyr2k clAmdBlasZsyr2k_pfn -#undef clAmdBlasZsyr2kEx -//#define clAmdBlasZsyr2kEx clAmdBlasZsyr2kEx_pfn -#undef clAmdBlasZsyrk -//#define clAmdBlasZsyrk clAmdBlasZsyrk_pfn -#undef clAmdBlasZsyrkEx -//#define clAmdBlasZsyrkEx clAmdBlasZsyrkEx_pfn -#undef clAmdBlasZtbmv -//#define clAmdBlasZtbmv clAmdBlasZtbmv_pfn -#undef clAmdBlasZtbsv -//#define clAmdBlasZtbsv clAmdBlasZtbsv_pfn -#undef clAmdBlasZtpmv -//#define clAmdBlasZtpmv clAmdBlasZtpmv_pfn -#undef clAmdBlasZtpsv -//#define clAmdBlasZtpsv clAmdBlasZtpsv_pfn -#undef clAmdBlasZtrmm -//#define clAmdBlasZtrmm clAmdBlasZtrmm_pfn -#undef clAmdBlasZtrmmEx -//#define clAmdBlasZtrmmEx clAmdBlasZtrmmEx_pfn -#undef clAmdBlasZtrmv -//#define clAmdBlasZtrmv clAmdBlasZtrmv_pfn -#undef clAmdBlasZtrsm -//#define clAmdBlasZtrsm clAmdBlasZtrsm_pfn -#undef clAmdBlasZtrsmEx -//#define clAmdBlasZtrsmEx clAmdBlasZtrsmEx_pfn -#undef clAmdBlasZtrsv -//#define clAmdBlasZtrsv clAmdBlasZtrsv_pfn -#undef clAmdBlasiCamax -//#define clAmdBlasiCamax clAmdBlasiCamax_pfn -#undef clAmdBlasiDamax -//#define clAmdBlasiDamax clAmdBlasiDamax_pfn -#undef clAmdBlasiSamax -//#define clAmdBlasiSamax clAmdBlasiSamax_pfn -#undef clAmdBlasiZamax -//#define clAmdBlasiZamax clAmdBlasiZamax_pfn - -// generated by parser_clamdblas.py -//extern CL_RUNTIME_EXPORT cl_ulong (*clAmdBlasAddScratchImage)(cl_context context, size_t width, size_t height, clAmdBlasStatus* status); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCaxpy)(size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCdotc)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCdotu)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, FloatComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, FloatComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, FloatComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgerc)(clAmdBlasOrder order, size_t M, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgeru)(clAmdBlasOrder order, size_t M, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChemm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChemv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, FloatComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, FloatComplex beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCher)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCher2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCher2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCherk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, float alpha, const cl_mem A, size_t offa, size_t lda, float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float2 alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChpr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChpr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCrotg)(cl_mem CA, size_t offCA, cl_mem CB, size_t offCB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCscal)(size_t N, cl_float2 alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_float C, cl_float S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsscal)(size_t N, cl_float alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, FloatComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t lda, FloatComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDaxpy)(size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDdot)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_double beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDger)(clAmdBlasOrder order, size_t M, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_double C, cl_double S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrotg)(cl_mem DA, size_t offDA, cl_mem DB, size_t offDB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrotm)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, const cl_mem DPARAM, size_t offDparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrotmg)(cl_mem DD1, size_t offDD1, cl_mem DD2, size_t offDD2, cl_mem DX1, size_t offDX1, const cl_mem DY1, size_t offDY1, cl_mem DPARAM, size_t offDparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDscal)(size_t N, cl_double alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDspmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDspr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDspr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsymv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsymvEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_double beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t lda, cl_double beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDzasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDznrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasGetVersion)(cl_uint* major, cl_uint* minor, cl_uint* patch); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasRemoveScratchImage)(cl_ulong imageID); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSaxpy)(size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasScasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasScnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasScopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSdot)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSetup)(); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_float beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSger)(clAmdBlasOrder order, size_t M, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_float C, cl_float S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrotg)(cl_mem SA, size_t offSA, cl_mem SB, size_t offSB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrotm)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, const cl_mem SPARAM, size_t offSparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrotmg)(cl_mem SD1, size_t offSD1, cl_mem SD2, size_t offSD2, cl_mem SX1, size_t offSX1, const cl_mem SY1, size_t offSY1, cl_mem SPARAM, size_t offSparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSscal)(size_t N, cl_float alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSspmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSspr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSspr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsymv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsymvEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_float beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t lda, cl_float beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -extern CL_RUNTIME_EXPORT void (*clAmdBlasTeardown)(); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZaxpy)(size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdotc)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdotu)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_double C, cl_double S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdscal)(size_t N, cl_double alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, DoubleComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, DoubleComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, DoubleComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgerc)(clAmdBlasOrder order, size_t M, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgeru)(clAmdBlasOrder order, size_t M, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhemm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhemv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, DoubleComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, DoubleComplex beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZher)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZher2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZher2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZherk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, double alpha, const cl_mem A, size_t offa, size_t lda, double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double2 alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhpr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhpr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZrotg)(cl_mem CA, size_t offCA, cl_mem CB, size_t offCB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZscal)(size_t N, cl_double2 alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, DoubleComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t lda, DoubleComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiCamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiDamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiSamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); -//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiZamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); diff --git a/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp b/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp deleted file mode 100644 index 1457d7eb8d69..000000000000 --- a/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// -// AUTOGENERATED, DO NOT EDIT -// -#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDFFT_HPP -#error "Invalid usage" -#endif - -// generated by parser_clamdfft.py -#define clAmdFftBakePlan clAmdFftBakePlan_ -#define clAmdFftCopyPlan clAmdFftCopyPlan_ -#define clAmdFftCreateDefaultPlan clAmdFftCreateDefaultPlan_ -#define clAmdFftDestroyPlan clAmdFftDestroyPlan_ -#define clAmdFftEnqueueTransform clAmdFftEnqueueTransform_ -#define clAmdFftGetLayout clAmdFftGetLayout_ -#define clAmdFftGetPlanBatchSize clAmdFftGetPlanBatchSize_ -#define clAmdFftGetPlanContext clAmdFftGetPlanContext_ -#define clAmdFftGetPlanDim clAmdFftGetPlanDim_ -#define clAmdFftGetPlanDistance clAmdFftGetPlanDistance_ -#define clAmdFftGetPlanInStride clAmdFftGetPlanInStride_ -#define clAmdFftGetPlanLength clAmdFftGetPlanLength_ -#define clAmdFftGetPlanOutStride clAmdFftGetPlanOutStride_ -#define clAmdFftGetPlanPrecision clAmdFftGetPlanPrecision_ -#define clAmdFftGetPlanScale clAmdFftGetPlanScale_ -#define clAmdFftGetPlanTransposeResult clAmdFftGetPlanTransposeResult_ -#define clAmdFftGetResultLocation clAmdFftGetResultLocation_ -#define clAmdFftGetTmpBufSize clAmdFftGetTmpBufSize_ -#define clAmdFftGetVersion clAmdFftGetVersion_ -#define clAmdFftSetLayout clAmdFftSetLayout_ -#define clAmdFftSetPlanBatchSize clAmdFftSetPlanBatchSize_ -#define clAmdFftSetPlanDim clAmdFftSetPlanDim_ -#define clAmdFftSetPlanDistance clAmdFftSetPlanDistance_ -#define clAmdFftSetPlanInStride clAmdFftSetPlanInStride_ -#define clAmdFftSetPlanLength clAmdFftSetPlanLength_ -#define clAmdFftSetPlanOutStride clAmdFftSetPlanOutStride_ -#define clAmdFftSetPlanPrecision clAmdFftSetPlanPrecision_ -#define clAmdFftSetPlanScale clAmdFftSetPlanScale_ -#define clAmdFftSetPlanTransposeResult clAmdFftSetPlanTransposeResult_ -#define clAmdFftSetResultLocation clAmdFftSetResultLocation_ -#define clAmdFftSetup clAmdFftSetup_ -#define clAmdFftTeardown clAmdFftTeardown_ - -#include - -// generated by parser_clamdfft.py -#undef clAmdFftBakePlan -#define clAmdFftBakePlan clAmdFftBakePlan_pfn -#undef clAmdFftCopyPlan -//#define clAmdFftCopyPlan clAmdFftCopyPlan_pfn -#undef clAmdFftCreateDefaultPlan -#define clAmdFftCreateDefaultPlan clAmdFftCreateDefaultPlan_pfn -#undef clAmdFftDestroyPlan -#define clAmdFftDestroyPlan clAmdFftDestroyPlan_pfn -#undef clAmdFftEnqueueTransform -#define clAmdFftEnqueueTransform clAmdFftEnqueueTransform_pfn -#undef clAmdFftGetLayout -//#define clAmdFftGetLayout clAmdFftGetLayout_pfn -#undef clAmdFftGetPlanBatchSize -//#define clAmdFftGetPlanBatchSize clAmdFftGetPlanBatchSize_pfn -#undef clAmdFftGetPlanContext -//#define clAmdFftGetPlanContext clAmdFftGetPlanContext_pfn -#undef clAmdFftGetPlanDim -//#define clAmdFftGetPlanDim clAmdFftGetPlanDim_pfn -#undef clAmdFftGetPlanDistance -//#define clAmdFftGetPlanDistance clAmdFftGetPlanDistance_pfn -#undef clAmdFftGetPlanInStride -//#define clAmdFftGetPlanInStride clAmdFftGetPlanInStride_pfn -#undef clAmdFftGetPlanLength -//#define clAmdFftGetPlanLength clAmdFftGetPlanLength_pfn -#undef clAmdFftGetPlanOutStride -//#define clAmdFftGetPlanOutStride clAmdFftGetPlanOutStride_pfn -#undef clAmdFftGetPlanPrecision -//#define clAmdFftGetPlanPrecision clAmdFftGetPlanPrecision_pfn -#undef clAmdFftGetPlanScale -//#define clAmdFftGetPlanScale clAmdFftGetPlanScale_pfn -#undef clAmdFftGetPlanTransposeResult -//#define clAmdFftGetPlanTransposeResult clAmdFftGetPlanTransposeResult_pfn -#undef clAmdFftGetResultLocation -//#define clAmdFftGetResultLocation clAmdFftGetResultLocation_pfn -#undef clAmdFftGetTmpBufSize -#define clAmdFftGetTmpBufSize clAmdFftGetTmpBufSize_pfn -#undef clAmdFftGetVersion -#define clAmdFftGetVersion clAmdFftGetVersion_pfn -#undef clAmdFftSetLayout -#define clAmdFftSetLayout clAmdFftSetLayout_pfn -#undef clAmdFftSetPlanBatchSize -#define clAmdFftSetPlanBatchSize clAmdFftSetPlanBatchSize_pfn -#undef clAmdFftSetPlanDim -//#define clAmdFftSetPlanDim clAmdFftSetPlanDim_pfn -#undef clAmdFftSetPlanDistance -#define clAmdFftSetPlanDistance clAmdFftSetPlanDistance_pfn -#undef clAmdFftSetPlanInStride -#define clAmdFftSetPlanInStride clAmdFftSetPlanInStride_pfn -#undef clAmdFftSetPlanLength -//#define clAmdFftSetPlanLength clAmdFftSetPlanLength_pfn -#undef clAmdFftSetPlanOutStride -#define clAmdFftSetPlanOutStride clAmdFftSetPlanOutStride_pfn -#undef clAmdFftSetPlanPrecision -#define clAmdFftSetPlanPrecision clAmdFftSetPlanPrecision_pfn -#undef clAmdFftSetPlanScale -#define clAmdFftSetPlanScale clAmdFftSetPlanScale_pfn -#undef clAmdFftSetPlanTransposeResult -//#define clAmdFftSetPlanTransposeResult clAmdFftSetPlanTransposeResult_pfn -#undef clAmdFftSetResultLocation -#define clAmdFftSetResultLocation clAmdFftSetResultLocation_pfn -#undef clAmdFftSetup -#define clAmdFftSetup clAmdFftSetup_pfn -#undef clAmdFftTeardown -#define clAmdFftTeardown clAmdFftTeardown_pfn - -// generated by parser_clamdfft.py -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftBakePlan)(clAmdFftPlanHandle plHandle, cl_uint numQueues, cl_command_queue* commQueueFFT, void (CL_CALLBACK* pfn_notify) (clAmdFftPlanHandle plHandle, void* user_data), void* user_data); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftCopyPlan)(clAmdFftPlanHandle* out_plHandle, cl_context new_context, clAmdFftPlanHandle in_plHandle); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftCreateDefaultPlan)(clAmdFftPlanHandle* plHandle, cl_context context, const clAmdFftDim dim, const size_t* clLengths); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftDestroyPlan)(clAmdFftPlanHandle* plHandle); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftEnqueueTransform)(clAmdFftPlanHandle plHandle, clAmdFftDirection dir, cl_uint numQueuesAndEvents, cl_command_queue* commQueues, cl_uint numWaitEvents, const cl_event* waitEvents, cl_event* outEvents, cl_mem* inputBuffers, cl_mem* outputBuffers, cl_mem tmpBuffer); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetLayout)(const clAmdFftPlanHandle plHandle, clAmdFftLayout* iLayout, clAmdFftLayout* oLayout); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanBatchSize)(const clAmdFftPlanHandle plHandle, size_t* batchSize); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanContext)(const clAmdFftPlanHandle plHandle, cl_context* context); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanDim)(const clAmdFftPlanHandle plHandle, clAmdFftDim* dim, cl_uint* size); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanDistance)(const clAmdFftPlanHandle plHandle, size_t* iDist, size_t* oDist); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanInStride)(const clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanLength)(const clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clLengths); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanOutStride)(const clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanPrecision)(const clAmdFftPlanHandle plHandle, clAmdFftPrecision* precision); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanScale)(const clAmdFftPlanHandle plHandle, clAmdFftDirection dir, cl_float* scale); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanTransposeResult)(const clAmdFftPlanHandle plHandle, clAmdFftResultTransposed* transposed); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetResultLocation)(const clAmdFftPlanHandle plHandle, clAmdFftResultLocation* placeness); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetTmpBufSize)(const clAmdFftPlanHandle plHandle, size_t* buffersize); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetVersion)(cl_uint* major, cl_uint* minor, cl_uint* patch); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetLayout)(clAmdFftPlanHandle plHandle, clAmdFftLayout iLayout, clAmdFftLayout oLayout); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanBatchSize)(clAmdFftPlanHandle plHandle, size_t batchSize); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanDim)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanDistance)(clAmdFftPlanHandle plHandle, size_t iDist, size_t oDist); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanInStride)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanLength)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim, const size_t* clLengths); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanOutStride)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanPrecision)(clAmdFftPlanHandle plHandle, clAmdFftPrecision precision); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanScale)(clAmdFftPlanHandle plHandle, clAmdFftDirection dir, cl_float scale); -//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanTransposeResult)(clAmdFftPlanHandle plHandle, clAmdFftResultTransposed transposed); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetResultLocation)(clAmdFftPlanHandle plHandle, clAmdFftResultLocation placeness); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetup)(const clAmdFftSetupData* setupData); -extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftTeardown)(); diff --git a/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp b/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp new file mode 100644 index 000000000000..2749927bea65 --- /dev/null +++ b/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp @@ -0,0 +1,602 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDBLAS_HPP +#error "Invalid usage" +#endif + +// generated by parser_clblas.py +#define clblasCaxpy clblasCaxpy_ +#define clblasCcopy clblasCcopy_ +#define clblasCdotc clblasCdotc_ +#define clblasCdotu clblasCdotu_ +#define clblasCgbmv clblasCgbmv_ +#define clblasCgemm clblasCgemm_ +#define clblasCgemv clblasCgemv_ +#define clblasCgerc clblasCgerc_ +#define clblasCgeru clblasCgeru_ +#define clblasChbmv clblasChbmv_ +#define clblasChemm clblasChemm_ +#define clblasChemv clblasChemv_ +#define clblasCher clblasCher_ +#define clblasCher2 clblasCher2_ +#define clblasCher2k clblasCher2k_ +#define clblasCherk clblasCherk_ +#define clblasChpmv clblasChpmv_ +#define clblasChpr clblasChpr_ +#define clblasChpr2 clblasChpr2_ +#define clblasCrotg clblasCrotg_ +#define clblasCscal clblasCscal_ +#define clblasCsrot clblasCsrot_ +#define clblasCsscal clblasCsscal_ +#define clblasCswap clblasCswap_ +#define clblasCsymm clblasCsymm_ +#define clblasCsyr2k clblasCsyr2k_ +#define clblasCsyrk clblasCsyrk_ +#define clblasCtbmv clblasCtbmv_ +#define clblasCtbsv clblasCtbsv_ +#define clblasCtpmv clblasCtpmv_ +#define clblasCtpsv clblasCtpsv_ +#define clblasCtrmm clblasCtrmm_ +#define clblasCtrmv clblasCtrmv_ +#define clblasCtrsm clblasCtrsm_ +#define clblasCtrsv clblasCtrsv_ +#define clblasDasum clblasDasum_ +#define clblasDaxpy clblasDaxpy_ +#define clblasDcopy clblasDcopy_ +#define clblasDdot clblasDdot_ +#define clblasDgbmv clblasDgbmv_ +#define clblasDgemm clblasDgemm_ +#define clblasDgemv clblasDgemv_ +#define clblasDger clblasDger_ +#define clblasDnrm2 clblasDnrm2_ +#define clblasDrot clblasDrot_ +#define clblasDrotg clblasDrotg_ +#define clblasDrotm clblasDrotm_ +#define clblasDrotmg clblasDrotmg_ +#define clblasDsbmv clblasDsbmv_ +#define clblasDscal clblasDscal_ +#define clblasDspmv clblasDspmv_ +#define clblasDspr clblasDspr_ +#define clblasDspr2 clblasDspr2_ +#define clblasDswap clblasDswap_ +#define clblasDsymm clblasDsymm_ +#define clblasDsymv clblasDsymv_ +#define clblasDsyr clblasDsyr_ +#define clblasDsyr2 clblasDsyr2_ +#define clblasDsyr2k clblasDsyr2k_ +#define clblasDsyrk clblasDsyrk_ +#define clblasDtbmv clblasDtbmv_ +#define clblasDtbsv clblasDtbsv_ +#define clblasDtpmv clblasDtpmv_ +#define clblasDtpsv clblasDtpsv_ +#define clblasDtrmm clblasDtrmm_ +#define clblasDtrmv clblasDtrmv_ +#define clblasDtrsm clblasDtrsm_ +#define clblasDtrsv clblasDtrsv_ +#define clblasDzasum clblasDzasum_ +#define clblasDznrm2 clblasDznrm2_ +#define clblasGetVersion clblasGetVersion_ +#define clblasSasum clblasSasum_ +#define clblasSaxpy clblasSaxpy_ +#define clblasScasum clblasScasum_ +#define clblasScnrm2 clblasScnrm2_ +#define clblasScopy clblasScopy_ +#define clblasSdot clblasSdot_ +#define clblasSetup clblasSetup_ +#define clblasSgbmv clblasSgbmv_ +#define clblasSgemm clblasSgemm_ +#define clblasSgemv clblasSgemv_ +#define clblasSger clblasSger_ +#define clblasSnrm2 clblasSnrm2_ +#define clblasSrot clblasSrot_ +#define clblasSrotg clblasSrotg_ +#define clblasSrotm clblasSrotm_ +#define clblasSrotmg clblasSrotmg_ +#define clblasSsbmv clblasSsbmv_ +#define clblasSscal clblasSscal_ +#define clblasSspmv clblasSspmv_ +#define clblasSspr clblasSspr_ +#define clblasSspr2 clblasSspr2_ +#define clblasSswap clblasSswap_ +#define clblasSsymm clblasSsymm_ +#define clblasSsymv clblasSsymv_ +#define clblasSsyr clblasSsyr_ +#define clblasSsyr2 clblasSsyr2_ +#define clblasSsyr2k clblasSsyr2k_ +#define clblasSsyrk clblasSsyrk_ +#define clblasStbmv clblasStbmv_ +#define clblasStbsv clblasStbsv_ +#define clblasStpmv clblasStpmv_ +#define clblasStpsv clblasStpsv_ +#define clblasStrmm clblasStrmm_ +#define clblasStrmv clblasStrmv_ +#define clblasStrsm clblasStrsm_ +#define clblasStrsv clblasStrsv_ +#define clblasTeardown clblasTeardown_ +#define clblasZaxpy clblasZaxpy_ +#define clblasZcopy clblasZcopy_ +#define clblasZdotc clblasZdotc_ +#define clblasZdotu clblasZdotu_ +#define clblasZdrot clblasZdrot_ +#define clblasZdscal clblasZdscal_ +#define clblasZgbmv clblasZgbmv_ +#define clblasZgemm clblasZgemm_ +#define clblasZgemv clblasZgemv_ +#define clblasZgerc clblasZgerc_ +#define clblasZgeru clblasZgeru_ +#define clblasZhbmv clblasZhbmv_ +#define clblasZhemm clblasZhemm_ +#define clblasZhemv clblasZhemv_ +#define clblasZher clblasZher_ +#define clblasZher2 clblasZher2_ +#define clblasZher2k clblasZher2k_ +#define clblasZherk clblasZherk_ +#define clblasZhpmv clblasZhpmv_ +#define clblasZhpr clblasZhpr_ +#define clblasZhpr2 clblasZhpr2_ +#define clblasZrotg clblasZrotg_ +#define clblasZscal clblasZscal_ +#define clblasZswap clblasZswap_ +#define clblasZsymm clblasZsymm_ +#define clblasZsyr2k clblasZsyr2k_ +#define clblasZsyrk clblasZsyrk_ +#define clblasZtbmv clblasZtbmv_ +#define clblasZtbsv clblasZtbsv_ +#define clblasZtpmv clblasZtpmv_ +#define clblasZtpsv clblasZtpsv_ +#define clblasZtrmm clblasZtrmm_ +#define clblasZtrmv clblasZtrmv_ +#define clblasZtrsm clblasZtrsm_ +#define clblasZtrsv clblasZtrsv_ +#define clblasiCamax clblasiCamax_ +#define clblasiDamax clblasiDamax_ +#define clblasiSamax clblasiSamax_ +#define clblasiZamax clblasiZamax_ + +#include + +// generated by parser_clblas.py +#undef clblasCaxpy +//#define clblasCaxpy clblasCaxpy_pfn +#undef clblasCcopy +//#define clblasCcopy clblasCcopy_pfn +#undef clblasCdotc +//#define clblasCdotc clblasCdotc_pfn +#undef clblasCdotu +//#define clblasCdotu clblasCdotu_pfn +#undef clblasCgbmv +//#define clblasCgbmv clblasCgbmv_pfn +#undef clblasCgemm +#define clblasCgemm clblasCgemm_pfn +#undef clblasCgemv +//#define clblasCgemv clblasCgemv_pfn +#undef clblasCgerc +//#define clblasCgerc clblasCgerc_pfn +#undef clblasCgeru +//#define clblasCgeru clblasCgeru_pfn +#undef clblasChbmv +//#define clblasChbmv clblasChbmv_pfn +#undef clblasChemm +//#define clblasChemm clblasChemm_pfn +#undef clblasChemv +//#define clblasChemv clblasChemv_pfn +#undef clblasCher +//#define clblasCher clblasCher_pfn +#undef clblasCher2 +//#define clblasCher2 clblasCher2_pfn +#undef clblasCher2k +//#define clblasCher2k clblasCher2k_pfn +#undef clblasCherk +//#define clblasCherk clblasCherk_pfn +#undef clblasChpmv +//#define clblasChpmv clblasChpmv_pfn +#undef clblasChpr +//#define clblasChpr clblasChpr_pfn +#undef clblasChpr2 +//#define clblasChpr2 clblasChpr2_pfn +#undef clblasCrotg +//#define clblasCrotg clblasCrotg_pfn +#undef clblasCscal +//#define clblasCscal clblasCscal_pfn +#undef clblasCsrot +//#define clblasCsrot clblasCsrot_pfn +#undef clblasCsscal +//#define clblasCsscal clblasCsscal_pfn +#undef clblasCswap +//#define clblasCswap clblasCswap_pfn +#undef clblasCsymm +//#define clblasCsymm clblasCsymm_pfn +#undef clblasCsyr2k +//#define clblasCsyr2k clblasCsyr2k_pfn +#undef clblasCsyrk +//#define clblasCsyrk clblasCsyrk_pfn +#undef clblasCtbmv +//#define clblasCtbmv clblasCtbmv_pfn +#undef clblasCtbsv +//#define clblasCtbsv clblasCtbsv_pfn +#undef clblasCtpmv +//#define clblasCtpmv clblasCtpmv_pfn +#undef clblasCtpsv +//#define clblasCtpsv clblasCtpsv_pfn +#undef clblasCtrmm +//#define clblasCtrmm clblasCtrmm_pfn +#undef clblasCtrmv +//#define clblasCtrmv clblasCtrmv_pfn +#undef clblasCtrsm +//#define clblasCtrsm clblasCtrsm_pfn +#undef clblasCtrsv +//#define clblasCtrsv clblasCtrsv_pfn +#undef clblasDasum +//#define clblasDasum clblasDasum_pfn +#undef clblasDaxpy +//#define clblasDaxpy clblasDaxpy_pfn +#undef clblasDcopy +//#define clblasDcopy clblasDcopy_pfn +#undef clblasDdot +//#define clblasDdot clblasDdot_pfn +#undef clblasDgbmv +//#define clblasDgbmv clblasDgbmv_pfn +#undef clblasDgemm +#define clblasDgemm clblasDgemm_pfn +#undef clblasDgemv +//#define clblasDgemv clblasDgemv_pfn +#undef clblasDger +//#define clblasDger clblasDger_pfn +#undef clblasDnrm2 +//#define clblasDnrm2 clblasDnrm2_pfn +#undef clblasDrot +//#define clblasDrot clblasDrot_pfn +#undef clblasDrotg +//#define clblasDrotg clblasDrotg_pfn +#undef clblasDrotm +//#define clblasDrotm clblasDrotm_pfn +#undef clblasDrotmg +//#define clblasDrotmg clblasDrotmg_pfn +#undef clblasDsbmv +//#define clblasDsbmv clblasDsbmv_pfn +#undef clblasDscal +//#define clblasDscal clblasDscal_pfn +#undef clblasDspmv +//#define clblasDspmv clblasDspmv_pfn +#undef clblasDspr +//#define clblasDspr clblasDspr_pfn +#undef clblasDspr2 +//#define clblasDspr2 clblasDspr2_pfn +#undef clblasDswap +//#define clblasDswap clblasDswap_pfn +#undef clblasDsymm +//#define clblasDsymm clblasDsymm_pfn +#undef clblasDsymv +//#define clblasDsymv clblasDsymv_pfn +#undef clblasDsyr +//#define clblasDsyr clblasDsyr_pfn +#undef clblasDsyr2 +//#define clblasDsyr2 clblasDsyr2_pfn +#undef clblasDsyr2k +//#define clblasDsyr2k clblasDsyr2k_pfn +#undef clblasDsyrk +//#define clblasDsyrk clblasDsyrk_pfn +#undef clblasDtbmv +//#define clblasDtbmv clblasDtbmv_pfn +#undef clblasDtbsv +//#define clblasDtbsv clblasDtbsv_pfn +#undef clblasDtpmv +//#define clblasDtpmv clblasDtpmv_pfn +#undef clblasDtpsv +//#define clblasDtpsv clblasDtpsv_pfn +#undef clblasDtrmm +//#define clblasDtrmm clblasDtrmm_pfn +#undef clblasDtrmv +//#define clblasDtrmv clblasDtrmv_pfn +#undef clblasDtrsm +//#define clblasDtrsm clblasDtrsm_pfn +#undef clblasDtrsv +//#define clblasDtrsv clblasDtrsv_pfn +#undef clblasDzasum +//#define clblasDzasum clblasDzasum_pfn +#undef clblasDznrm2 +//#define clblasDznrm2 clblasDznrm2_pfn +#undef clblasGetVersion +//#define clblasGetVersion clblasGetVersion_pfn +#undef clblasSasum +//#define clblasSasum clblasSasum_pfn +#undef clblasSaxpy +//#define clblasSaxpy clblasSaxpy_pfn +#undef clblasScasum +//#define clblasScasum clblasScasum_pfn +#undef clblasScnrm2 +//#define clblasScnrm2 clblasScnrm2_pfn +#undef clblasScopy +//#define clblasScopy clblasScopy_pfn +#undef clblasSdot +//#define clblasSdot clblasSdot_pfn +#undef clblasSetup +#define clblasSetup clblasSetup_pfn +#undef clblasSgbmv +//#define clblasSgbmv clblasSgbmv_pfn +#undef clblasSgemm +#define clblasSgemm clblasSgemm_pfn +#undef clblasSgemv +//#define clblasSgemv clblasSgemv_pfn +#undef clblasSger +//#define clblasSger clblasSger_pfn +#undef clblasSnrm2 +//#define clblasSnrm2 clblasSnrm2_pfn +#undef clblasSrot +//#define clblasSrot clblasSrot_pfn +#undef clblasSrotg +//#define clblasSrotg clblasSrotg_pfn +#undef clblasSrotm +//#define clblasSrotm clblasSrotm_pfn +#undef clblasSrotmg +//#define clblasSrotmg clblasSrotmg_pfn +#undef clblasSsbmv +//#define clblasSsbmv clblasSsbmv_pfn +#undef clblasSscal +//#define clblasSscal clblasSscal_pfn +#undef clblasSspmv +//#define clblasSspmv clblasSspmv_pfn +#undef clblasSspr +//#define clblasSspr clblasSspr_pfn +#undef clblasSspr2 +//#define clblasSspr2 clblasSspr2_pfn +#undef clblasSswap +//#define clblasSswap clblasSswap_pfn +#undef clblasSsymm +//#define clblasSsymm clblasSsymm_pfn +#undef clblasSsymv +//#define clblasSsymv clblasSsymv_pfn +#undef clblasSsyr +//#define clblasSsyr clblasSsyr_pfn +#undef clblasSsyr2 +//#define clblasSsyr2 clblasSsyr2_pfn +#undef clblasSsyr2k +//#define clblasSsyr2k clblasSsyr2k_pfn +#undef clblasSsyrk +//#define clblasSsyrk clblasSsyrk_pfn +#undef clblasStbmv +//#define clblasStbmv clblasStbmv_pfn +#undef clblasStbsv +//#define clblasStbsv clblasStbsv_pfn +#undef clblasStpmv +//#define clblasStpmv clblasStpmv_pfn +#undef clblasStpsv +//#define clblasStpsv clblasStpsv_pfn +#undef clblasStrmm +//#define clblasStrmm clblasStrmm_pfn +#undef clblasStrmv +//#define clblasStrmv clblasStrmv_pfn +#undef clblasStrsm +//#define clblasStrsm clblasStrsm_pfn +#undef clblasStrsv +//#define clblasStrsv clblasStrsv_pfn +#undef clblasTeardown +#define clblasTeardown clblasTeardown_pfn +#undef clblasZaxpy +//#define clblasZaxpy clblasZaxpy_pfn +#undef clblasZcopy +//#define clblasZcopy clblasZcopy_pfn +#undef clblasZdotc +//#define clblasZdotc clblasZdotc_pfn +#undef clblasZdotu +//#define clblasZdotu clblasZdotu_pfn +#undef clblasZdrot +//#define clblasZdrot clblasZdrot_pfn +#undef clblasZdscal +//#define clblasZdscal clblasZdscal_pfn +#undef clblasZgbmv +//#define clblasZgbmv clblasZgbmv_pfn +#undef clblasZgemm +#define clblasZgemm clblasZgemm_pfn +#undef clblasZgemv +//#define clblasZgemv clblasZgemv_pfn +#undef clblasZgerc +//#define clblasZgerc clblasZgerc_pfn +#undef clblasZgeru +//#define clblasZgeru clblasZgeru_pfn +#undef clblasZhbmv +//#define clblasZhbmv clblasZhbmv_pfn +#undef clblasZhemm +//#define clblasZhemm clblasZhemm_pfn +#undef clblasZhemv +//#define clblasZhemv clblasZhemv_pfn +#undef clblasZher +//#define clblasZher clblasZher_pfn +#undef clblasZher2 +//#define clblasZher2 clblasZher2_pfn +#undef clblasZher2k +//#define clblasZher2k clblasZher2k_pfn +#undef clblasZherk +//#define clblasZherk clblasZherk_pfn +#undef clblasZhpmv +//#define clblasZhpmv clblasZhpmv_pfn +#undef clblasZhpr +//#define clblasZhpr clblasZhpr_pfn +#undef clblasZhpr2 +//#define clblasZhpr2 clblasZhpr2_pfn +#undef clblasZrotg +//#define clblasZrotg clblasZrotg_pfn +#undef clblasZscal +//#define clblasZscal clblasZscal_pfn +#undef clblasZswap +//#define clblasZswap clblasZswap_pfn +#undef clblasZsymm +//#define clblasZsymm clblasZsymm_pfn +#undef clblasZsyr2k +//#define clblasZsyr2k clblasZsyr2k_pfn +#undef clblasZsyrk +//#define clblasZsyrk clblasZsyrk_pfn +#undef clblasZtbmv +//#define clblasZtbmv clblasZtbmv_pfn +#undef clblasZtbsv +//#define clblasZtbsv clblasZtbsv_pfn +#undef clblasZtpmv +//#define clblasZtpmv clblasZtpmv_pfn +#undef clblasZtpsv +//#define clblasZtpsv clblasZtpsv_pfn +#undef clblasZtrmm +//#define clblasZtrmm clblasZtrmm_pfn +#undef clblasZtrmv +//#define clblasZtrmv clblasZtrmv_pfn +#undef clblasZtrsm +//#define clblasZtrsm clblasZtrsm_pfn +#undef clblasZtrsv +//#define clblasZtrsv clblasZtrsv_pfn +#undef clblasiCamax +//#define clblasiCamax clblasiCamax_pfn +#undef clblasiDamax +//#define clblasiDamax clblasiDamax_pfn +#undef clblasiSamax +//#define clblasiSamax clblasiSamax_pfn +#undef clblasiZamax +//#define clblasiZamax clblasiZamax_pfn + +// generated by parser_clblas.py +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCaxpy)(size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCdotc)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCdotu)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCgbmv)(clblasOrder order, clblasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clblasStatus (*clblasCgemm)(clblasOrder order, clblasTranspose transA, clblasTranspose transB, size_t M, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCgemv)(clblasOrder order, clblasTranspose transA, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, FloatComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCgerc)(clblasOrder order, size_t M, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCgeru)(clblasOrder order, size_t M, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasChbmv)(clblasOrder order, clblasUplo uplo, size_t N, size_t K, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasChemm)(clblasOrder order, clblasSide side, clblasUplo uplo, size_t M, size_t N, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasChemv)(clblasOrder order, clblasUplo uplo, size_t N, FloatComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, FloatComplex beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCher)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCher2)(clblasOrder order, clblasUplo uplo, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCher2k)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCherk)(clblasOrder order, clblasUplo uplo, clblasTranspose transA, size_t N, size_t K, float alpha, const cl_mem A, size_t offa, size_t lda, float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasChpmv)(clblasOrder order, clblasUplo uplo, size_t N, cl_float2 alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasChpr)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasChpr2)(clblasOrder order, clblasUplo uplo, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCrotg)(cl_mem CA, size_t offCA, cl_mem CB, size_t offCB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCscal)(size_t N, cl_float2 alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCsrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_float C, cl_float S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCsscal)(size_t N, cl_float alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCsymm)(clblasOrder order, clblasSide side, clblasUplo uplo, size_t M, size_t N, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCsyr2k)(clblasOrder order, clblasUplo uplo, clblasTranspose transAB, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCsyrk)(clblasOrder order, clblasUplo uplo, clblasTranspose transA, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtbmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtbsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtpmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtpsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtrmm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtrmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtrsm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasCtrsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDaxpy)(size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDdot)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDgbmv)(clblasOrder order, clblasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clblasStatus (*clblasDgemm)(clblasOrder order, clblasTranspose transA, clblasTranspose transB, size_t M, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDgemv)(clblasOrder order, clblasTranspose transA, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDger)(clblasOrder order, size_t M, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_double C, cl_double S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDrotg)(cl_mem DA, size_t offDA, cl_mem DB, size_t offDB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDrotm)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, const cl_mem DPARAM, size_t offDparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDrotmg)(cl_mem DD1, size_t offDD1, cl_mem DD2, size_t offDD2, cl_mem DX1, size_t offDX1, const cl_mem DY1, size_t offDY1, cl_mem DPARAM, size_t offDparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsbmv)(clblasOrder order, clblasUplo uplo, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDscal)(size_t N, cl_double alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDspmv)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDspr)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDspr2)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsymm)(clblasOrder order, clblasSide side, clblasUplo uplo, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsymv)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsyr)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsyr2)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsyr2k)(clblasOrder order, clblasUplo uplo, clblasTranspose transAB, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDsyrk)(clblasOrder order, clblasUplo uplo, clblasTranspose transA, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtbmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtbsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtpmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtpsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtrmm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtrmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtrsm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDtrsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDzasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasDznrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasGetVersion)(cl_uint* major, cl_uint* minor, cl_uint* patch); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSaxpy)(size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasScasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasScnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasScopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSdot)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clblasStatus (*clblasSetup)(); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSgbmv)(clblasOrder order, clblasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clblasStatus (*clblasSgemm)(clblasOrder order, clblasTranspose transA, clblasTranspose transB, size_t M, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSgemv)(clblasOrder order, clblasTranspose transA, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSger)(clblasOrder order, size_t M, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_float C, cl_float S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSrotg)(cl_mem SA, size_t offSA, cl_mem SB, size_t offSB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSrotm)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, const cl_mem SPARAM, size_t offSparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSrotmg)(cl_mem SD1, size_t offSD1, cl_mem SD2, size_t offSD2, cl_mem SX1, size_t offSX1, const cl_mem SY1, size_t offSY1, cl_mem SPARAM, size_t offSparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsbmv)(clblasOrder order, clblasUplo uplo, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSscal)(size_t N, cl_float alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSspmv)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSspr)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSspr2)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsymm)(clblasOrder order, clblasSide side, clblasUplo uplo, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsymv)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsyr)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsyr2)(clblasOrder order, clblasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsyr2k)(clblasOrder order, clblasUplo uplo, clblasTranspose transAB, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasSsyrk)(clblasOrder order, clblasUplo uplo, clblasTranspose transA, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStbmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStbsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStpmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStpsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStrmm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStrmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStrsm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasStrsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT void (*clblasTeardown)(); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZaxpy)(size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZdotc)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZdotu)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZdrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_double C, cl_double S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZdscal)(size_t N, cl_double alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZgbmv)(clblasOrder order, clblasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clblasStatus (*clblasZgemm)(clblasOrder order, clblasTranspose transA, clblasTranspose transB, size_t M, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZgemv)(clblasOrder order, clblasTranspose transA, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, DoubleComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZgerc)(clblasOrder order, size_t M, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZgeru)(clblasOrder order, size_t M, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZhbmv)(clblasOrder order, clblasUplo uplo, size_t N, size_t K, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZhemm)(clblasOrder order, clblasSide side, clblasUplo uplo, size_t M, size_t N, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZhemv)(clblasOrder order, clblasUplo uplo, size_t N, DoubleComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, DoubleComplex beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZher)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZher2)(clblasOrder order, clblasUplo uplo, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZher2k)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZherk)(clblasOrder order, clblasUplo uplo, clblasTranspose transA, size_t N, size_t K, double alpha, const cl_mem A, size_t offa, size_t lda, double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZhpmv)(clblasOrder order, clblasUplo uplo, size_t N, cl_double2 alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZhpr)(clblasOrder order, clblasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZhpr2)(clblasOrder order, clblasUplo uplo, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZrotg)(cl_mem CA, size_t offCA, cl_mem CB, size_t offCB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZscal)(size_t N, cl_double2 alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZsymm)(clblasOrder order, clblasSide side, clblasUplo uplo, size_t M, size_t N, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZsyr2k)(clblasOrder order, clblasUplo uplo, clblasTranspose transAB, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZsyrk)(clblasOrder order, clblasUplo uplo, clblasTranspose transA, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtbmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtbsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtpmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtpsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtrmm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtrmv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtrsm)(clblasOrder order, clblasSide side, clblasUplo uplo, clblasTranspose transA, clblasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasZtrsv)(clblasOrder order, clblasUplo uplo, clblasTranspose trans, clblasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasiCamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasiDamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasiSamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clblasStatus (*clblasiZamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); diff --git a/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp b/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp new file mode 100644 index 000000000000..dff3b406a611 --- /dev/null +++ b/modules/core/include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp @@ -0,0 +1,146 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDFFT_HPP +#error "Invalid usage" +#endif + +// generated by parser_clfft.py +#define clfftBakePlan clfftBakePlan_ +#define clfftCopyPlan clfftCopyPlan_ +#define clfftCreateDefaultPlan clfftCreateDefaultPlan_ +#define clfftDestroyPlan clfftDestroyPlan_ +#define clfftEnqueueTransform clfftEnqueueTransform_ +#define clfftGetLayout clfftGetLayout_ +#define clfftGetPlanBatchSize clfftGetPlanBatchSize_ +#define clfftGetPlanContext clfftGetPlanContext_ +#define clfftGetPlanDim clfftGetPlanDim_ +#define clfftGetPlanDistance clfftGetPlanDistance_ +#define clfftGetPlanInStride clfftGetPlanInStride_ +#define clfftGetPlanLength clfftGetPlanLength_ +#define clfftGetPlanOutStride clfftGetPlanOutStride_ +#define clfftGetPlanPrecision clfftGetPlanPrecision_ +#define clfftGetPlanScale clfftGetPlanScale_ +#define clfftGetPlanTransposeResult clfftGetPlanTransposeResult_ +#define clfftGetResultLocation clfftGetResultLocation_ +#define clfftGetTmpBufSize clfftGetTmpBufSize_ +#define clfftGetVersion clfftGetVersion_ +#define clfftSetLayout clfftSetLayout_ +#define clfftSetPlanBatchSize clfftSetPlanBatchSize_ +#define clfftSetPlanCallback clfftSetPlanCallback_ +#define clfftSetPlanDim clfftSetPlanDim_ +#define clfftSetPlanDistance clfftSetPlanDistance_ +#define clfftSetPlanInStride clfftSetPlanInStride_ +#define clfftSetPlanLength clfftSetPlanLength_ +#define clfftSetPlanOutStride clfftSetPlanOutStride_ +#define clfftSetPlanPrecision clfftSetPlanPrecision_ +#define clfftSetPlanScale clfftSetPlanScale_ +#define clfftSetPlanTransposeResult clfftSetPlanTransposeResult_ +#define clfftSetResultLocation clfftSetResultLocation_ +#define clfftSetup clfftSetup_ +#define clfftTeardown clfftTeardown_ + +#include + +// generated by parser_clfft.py +#undef clfftBakePlan +#define clfftBakePlan clfftBakePlan_pfn +#undef clfftCopyPlan +//#define clfftCopyPlan clfftCopyPlan_pfn +#undef clfftCreateDefaultPlan +#define clfftCreateDefaultPlan clfftCreateDefaultPlan_pfn +#undef clfftDestroyPlan +#define clfftDestroyPlan clfftDestroyPlan_pfn +#undef clfftEnqueueTransform +#define clfftEnqueueTransform clfftEnqueueTransform_pfn +#undef clfftGetLayout +//#define clfftGetLayout clfftGetLayout_pfn +#undef clfftGetPlanBatchSize +//#define clfftGetPlanBatchSize clfftGetPlanBatchSize_pfn +#undef clfftGetPlanContext +//#define clfftGetPlanContext clfftGetPlanContext_pfn +#undef clfftGetPlanDim +//#define clfftGetPlanDim clfftGetPlanDim_pfn +#undef clfftGetPlanDistance +//#define clfftGetPlanDistance clfftGetPlanDistance_pfn +#undef clfftGetPlanInStride +//#define clfftGetPlanInStride clfftGetPlanInStride_pfn +#undef clfftGetPlanLength +//#define clfftGetPlanLength clfftGetPlanLength_pfn +#undef clfftGetPlanOutStride +//#define clfftGetPlanOutStride clfftGetPlanOutStride_pfn +#undef clfftGetPlanPrecision +//#define clfftGetPlanPrecision clfftGetPlanPrecision_pfn +#undef clfftGetPlanScale +//#define clfftGetPlanScale clfftGetPlanScale_pfn +#undef clfftGetPlanTransposeResult +//#define clfftGetPlanTransposeResult clfftGetPlanTransposeResult_pfn +#undef clfftGetResultLocation +//#define clfftGetResultLocation clfftGetResultLocation_pfn +#undef clfftGetTmpBufSize +#define clfftGetTmpBufSize clfftGetTmpBufSize_pfn +#undef clfftGetVersion +#define clfftGetVersion clfftGetVersion_pfn +#undef clfftSetLayout +#define clfftSetLayout clfftSetLayout_pfn +#undef clfftSetPlanBatchSize +#define clfftSetPlanBatchSize clfftSetPlanBatchSize_pfn +#undef clfftSetPlanCallback +//#define clfftSetPlanCallback clfftSetPlanCallback_pfn +#undef clfftSetPlanDim +//#define clfftSetPlanDim clfftSetPlanDim_pfn +#undef clfftSetPlanDistance +#define clfftSetPlanDistance clfftSetPlanDistance_pfn +#undef clfftSetPlanInStride +#define clfftSetPlanInStride clfftSetPlanInStride_pfn +#undef clfftSetPlanLength +//#define clfftSetPlanLength clfftSetPlanLength_pfn +#undef clfftSetPlanOutStride +#define clfftSetPlanOutStride clfftSetPlanOutStride_pfn +#undef clfftSetPlanPrecision +#define clfftSetPlanPrecision clfftSetPlanPrecision_pfn +#undef clfftSetPlanScale +#define clfftSetPlanScale clfftSetPlanScale_pfn +#undef clfftSetPlanTransposeResult +//#define clfftSetPlanTransposeResult clfftSetPlanTransposeResult_pfn +#undef clfftSetResultLocation +#define clfftSetResultLocation clfftSetResultLocation_pfn +#undef clfftSetup +#define clfftSetup clfftSetup_pfn +#undef clfftTeardown +#define clfftTeardown clfftTeardown_pfn + +// generated by parser_clfft.py +extern CL_RUNTIME_EXPORT clfftStatus (*clfftBakePlan)(clfftPlanHandle plHandle, cl_uint numQueues, cl_command_queue* commQueueFFT, void (CL_CALLBACK* pfn_notify) (clfftPlanHandle plHandle, void* user_data), void* user_data); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftCopyPlan)(clfftPlanHandle* out_plHandle, cl_context new_context, clfftPlanHandle in_plHandle); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftCreateDefaultPlan)(clfftPlanHandle* plHandle, cl_context context, const clfftDim dim, const size_t* clLengths); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftDestroyPlan)(clfftPlanHandle* plHandle); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftEnqueueTransform)(clfftPlanHandle plHandle, clfftDirection dir, cl_uint numQueuesAndEvents, cl_command_queue* commQueues, cl_uint numWaitEvents, const cl_event* waitEvents, cl_event* outEvents, cl_mem* inputBuffers, cl_mem* outputBuffers, cl_mem tmpBuffer); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetLayout)(const clfftPlanHandle plHandle, clfftLayout* iLayout, clfftLayout* oLayout); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanBatchSize)(const clfftPlanHandle plHandle, size_t* batchSize); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanContext)(const clfftPlanHandle plHandle, cl_context* context); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanDim)(const clfftPlanHandle plHandle, clfftDim* dim, cl_uint* size); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanDistance)(const clfftPlanHandle plHandle, size_t* iDist, size_t* oDist); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanInStride)(const clfftPlanHandle plHandle, const clfftDim dim, size_t* clStrides); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanLength)(const clfftPlanHandle plHandle, const clfftDim dim, size_t* clLengths); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanOutStride)(const clfftPlanHandle plHandle, const clfftDim dim, size_t* clStrides); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanPrecision)(const clfftPlanHandle plHandle, clfftPrecision* precision); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanScale)(const clfftPlanHandle plHandle, clfftDirection dir, cl_float* scale); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetPlanTransposeResult)(const clfftPlanHandle plHandle, clfftResultTransposed* transposed); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetResultLocation)(const clfftPlanHandle plHandle, clfftResultLocation* placeness); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetTmpBufSize)(const clfftPlanHandle plHandle, size_t* buffersize); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftGetVersion)(cl_uint* major, cl_uint* minor, cl_uint* patch); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetLayout)(clfftPlanHandle plHandle, clfftLayout iLayout, clfftLayout oLayout); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanBatchSize)(clfftPlanHandle plHandle, size_t batchSize); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanCallback)(clfftPlanHandle plHandle, const char* funcName, const char* funcString, int localMemSize, clfftCallbackType callbackType, cl_mem* userdata, int numUserdataBuffers); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanDim)(clfftPlanHandle plHandle, const clfftDim dim); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanDistance)(clfftPlanHandle plHandle, size_t iDist, size_t oDist); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanInStride)(clfftPlanHandle plHandle, const clfftDim dim, size_t* clStrides); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanLength)(clfftPlanHandle plHandle, const clfftDim dim, const size_t* clLengths); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanOutStride)(clfftPlanHandle plHandle, const clfftDim dim, size_t* clStrides); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanPrecision)(clfftPlanHandle plHandle, clfftPrecision precision); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanScale)(clfftPlanHandle plHandle, clfftDirection dir, cl_float scale); +//extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetPlanTransposeResult)(clfftPlanHandle plHandle, clfftResultTransposed transposed); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetResultLocation)(clfftPlanHandle plHandle, clfftResultLocation placeness); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftSetup)(const clfftSetupData* setupData); +extern CL_RUNTIME_EXPORT clfftStatus (*clfftTeardown)(); diff --git a/modules/core/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp b/modules/core/include/opencv2/core/opencl/runtime/opencl_clblas.hpp similarity index 98% rename from modules/core/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp rename to modules/core/include/opencv2/core/opencl/runtime/opencl_clblas.hpp index 2ad8ac0b5db8..ccddf8f76c19 100644 --- a/modules/core/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp +++ b/modules/core/include/opencv2/core/opencl/runtime/opencl_clblas.hpp @@ -46,7 +46,7 @@ #include "opencl_core.hpp" -#include "autogenerated/opencl_clamdblas.hpp" +#include "autogenerated/opencl_clblas.hpp" #endif // HAVE_CLAMDBLAS diff --git a/modules/core/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp b/modules/core/include/opencv2/core/opencl/runtime/opencl_clfft.hpp similarity index 98% rename from modules/core/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp rename to modules/core/include/opencv2/core/opencl/runtime/opencl_clfft.hpp index a328f722fcca..7f4af5e60b7e 100644 --- a/modules/core/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp +++ b/modules/core/include/opencv2/core/opencl/runtime/opencl_clfft.hpp @@ -46,7 +46,7 @@ #include "opencl_core.hpp" -#include "autogenerated/opencl_clamdfft.hpp" +#include "autogenerated/opencl_clfft.hpp" #endif // HAVE_CLAMDFFT diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index 97aeab375ffd..32f3c8c99998 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -358,7 +358,11 @@ _IplImage needed for correct deallocation */ #if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) - _IplImage() {} + _IplImage() + { + memset(this, 0, sizeof(*this)); // valid for POD structure + nSize = sizeof(IplImage); + } _IplImage(const cv::Mat& m) { *this = cvIplImage(m); } #endif } diff --git a/modules/core/include/opencv2/core/utility.hpp b/modules/core/include/opencv2/core/utility.hpp index f0368027aa6a..108c0d93e749 100644 --- a/modules/core/include/opencv2/core/utility.hpp +++ b/modules/core/include/opencv2/core/utility.hpp @@ -714,9 +714,27 @@ void Mat::forEach_impl(const Functor& operation) { /////////////////////////// Synchronization Primitives /////////////////////////////// #if !defined(_M_CEE) +#ifndef OPENCV_DISABLE_THREAD_SUPPORT typedef std::recursive_mutex Mutex; typedef std::lock_guard AutoLock; -#endif +#else // OPENCV_DISABLE_THREAD_SUPPORT +// Custom (failing) implementation of `std::recursive_mutex`. +struct Mutex { + void lock(){ + CV_Error(cv::Error::StsNotImplemented, + "cv::Mutex is disabled by OPENCV_DISABLE_THREAD_SUPPORT=ON"); + } + void unlock(){ + CV_Error(cv::Error::StsNotImplemented, + "cv::Mutex is disabled by OPENCV_DISABLE_THREAD_SUPPORT=ON"); + } +}; +// Stub for cv::AutoLock when threads are disabled. +struct AutoLock { + AutoLock(Mutex &) { } +}; +#endif // OPENCV_DISABLE_THREAD_SUPPORT +#endif // !defined(_M_CEE) /** @brief Designed for command line parsing diff --git a/modules/core/include/opencv2/core/utils/filesystem.private.hpp b/modules/core/include/opencv2/core/utils/filesystem.private.hpp index ea2591c9de1d..72b2bb947968 100644 --- a/modules/core/include/opencv2/core/utils/filesystem.private.hpp +++ b/modules/core/include/opencv2/core/utils/filesystem.private.hpp @@ -16,8 +16,8 @@ # define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 # elif defined(__APPLE__) # include -# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (!defined(TARGET_OS_OSX) && !TARGET_OS_IPHONE) -# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX only +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS) +# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX, iOS only # endif # else /* unknown */ diff --git a/modules/core/include/opencv2/core/utils/plugin_loader.private.hpp b/modules/core/include/opencv2/core/utils/plugin_loader.private.hpp index bc3ae4d08a7a..d6390fc74a48 100644 --- a/modules/core/include/opencv2/core/utils/plugin_loader.private.hpp +++ b/modules/core/include/opencv2/core/utils/plugin_loader.private.hpp @@ -80,7 +80,9 @@ LibHandle_t libraryLoad_(const FileSystemPath_t& filename) return LoadLibraryW(filename.c_str()); #endif #elif defined(__linux__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__GLIBC__) - return dlopen(filename.c_str(), RTLD_NOW); + void* handle = dlopen(filename.c_str(), RTLD_NOW); + CV_LOG_IF_DEBUG(NULL, !handle, "dlopen() error: " << dlerror()); + return handle; #endif } diff --git a/modules/core/include/opencv2/core/version.hpp b/modules/core/include/opencv2/core/version.hpp index ad6c36157736..f627d7147265 100644 --- a/modules/core/include/opencv2/core/version.hpp +++ b/modules/core/include/opencv2/core/version.hpp @@ -7,7 +7,7 @@ #define CV_VERSION_MAJOR 4 #define CV_VERSION_MINOR 5 -#define CV_VERSION_REVISION 2 +#define CV_VERSION_REVISION 3 #define CV_VERSION_STATUS "-dev" #define CVAUX_STR_EXP(__A) #__A diff --git a/modules/core/misc/java/src/java/core+Mat.java b/modules/core/misc/java/src/java/core+Mat.java index 641d9f8ae843..5fcc72773873 100644 --- a/modules/core/misc/java/src/java/core+Mat.java +++ b/modules/core/misc/java/src/java/core+Mat.java @@ -1128,6 +1128,458 @@ public int width() { return cols(); } + // javadoc:Mat::at(clazz, row, col) + @SuppressWarnings("unchecked") + public Atable at(Class clazz, int row, int col) { + if (clazz == Byte.class || clazz == byte.class) { + return (Atable)new AtableByte(this, row, col); + } else if (clazz == Double.class || clazz == double.class) { + return (Atable)new AtableDouble(this, row, col); + } else if (clazz == Float.class || clazz == float.class) { + return (Atable)new AtableFloat(this, row, col); + } else if (clazz == Integer.class || clazz == int.class) { + return (Atable)new AtableInteger(this, row, col); + } else if (clazz == Short.class || clazz == short.class) { + return (Atable)new AtableShort(this, row, col); + } else { + throw new RuntimeException("Unsupported class type"); + } + } + + // javadoc:Mat::at(clazz, idx) + @SuppressWarnings("unchecked") + public Atable at(Class clazz, int[] idx) { + if (clazz == Byte.class || clazz == byte.class) { + return (Atable)new AtableByte(this, idx); + } else if (clazz == Double.class || clazz == double.class) { + return (Atable)new AtableDouble(this, idx); + } else if (clazz == Float.class || clazz == float.class) { + return (Atable)new AtableFloat(this, idx); + } else if (clazz == Integer.class || clazz == int.class) { + return (Atable)new AtableInteger(this, idx); + } else if (clazz == Short.class || clazz == short.class) { + return (Atable)new AtableShort(this, idx); + } else { + throw new RuntimeException("Unsupported class parameter"); + } + } + + public static class Tuple2 { + public Tuple2(T _0, T _1) { + this._0 = _0; + this._1 = _1; + } + + public T get_0() { + return _0; + } + + public T get_1() { + return _1; + } + + private final T _0; + private final T _1; + } + + public static class Tuple3 { + public Tuple3(T _0, T _1, T _2) { + this._0 = _0; + this._1 = _1; + this._2 = _2; + } + + public T get_0() { + return _0; + } + + public T get_1() { + return _1; + } + + public T get_2() { + return _2; + } + + private final T _0; + private final T _1; + private final T _2; + } + + public static class Tuple4 { + public Tuple4(T _0, T _1, T _2, T _3) { + this._0 = _0; + this._1 = _1; + this._2 = _2; + this._3 = _3; + } + + public T get_0() { + return _0; + } + + public T get_1() { + return _1; + } + + public T get_2() { + return _2; + } + + public T get_3() { + return _3; + } + + private final T _0; + private final T _1; + private final T _2; + private final T _3; + } + + public interface Atable { + T getV(); + void setV(T v); + Tuple2 getV2c(); + void setV2c(Tuple2 v); + Tuple3 getV3c(); + void setV3c(Tuple3 v); + Tuple4 getV4c(); + void setV4c(Tuple4 v); + } + + private static class AtableBase { + + protected AtableBase(Mat mat, int row, int col) { + this.mat = mat; + indices = new int[2]; + indices[0] = row; + indices[1] = col; + } + + protected AtableBase(Mat mat, int[] indices) { + this.mat = mat; + this.indices = indices; + } + + protected final Mat mat; + protected final int[] indices; + } + + private static class AtableByte extends AtableBase implements Atable { + + public AtableByte(Mat mat, int row, int col) { + super(mat, row, col); + } + + public AtableByte(Mat mat, int[] indices) { + super(mat, indices); + } + + @Override + public Byte getV() { + byte[] data = new byte[1]; + mat.get(indices, data); + return data[0]; + } + + @Override + public void setV(Byte v) { + byte[] data = new byte[] { v }; + mat.put(indices, data); + } + + @Override + public Tuple2 getV2c() { + byte[] data = new byte[2]; + mat.get(indices, data); + return new Tuple2(data[0], data[1]); + } + + @Override + public void setV2c(Tuple2 v) { + byte[] data = new byte[] { v._0, v._1 }; + mat.put(indices, data); + } + + @Override + public Tuple3 getV3c() { + byte[] data = new byte[3]; + mat.get(indices, data); + return new Tuple3(data[0], data[1], data[2]); + } + + @Override + public void setV3c(Tuple3 v) { + byte[] data = new byte[] { v._0, v._1, v._2 }; + mat.put(indices, data); + } + + @Override + public Tuple4 getV4c() { + byte[] data = new byte[4]; + mat.get(indices, data); + return new Tuple4(data[0], data[1], data[2], data[3]); + } + + @Override + public void setV4c(Tuple4 v) { + byte[] data = new byte[] { v._0, v._1, v._2, v._3 }; + mat.put(indices, data); + } + } + + private static class AtableDouble extends AtableBase implements Atable { + + public AtableDouble(Mat mat, int row, int col) { + super(mat, row, col); + } + + public AtableDouble(Mat mat, int[] indices) { + super(mat, indices); + } + + @Override + public Double getV() { + double[] data = new double[1]; + mat.get(indices, data); + return data[0]; + } + + @Override + public void setV(Double v) { + double[] data = new double[] { v }; + mat.put(indices, data); + } + + @Override + public Tuple2 getV2c() { + double[] data = new double[2]; + mat.get(indices, data); + return new Tuple2(data[0], data[1]); + } + + @Override + public void setV2c(Tuple2 v) { + double[] data = new double[] { v._0, v._1 }; + mat.put(indices, data); + } + + @Override + public Tuple3 getV3c() { + double[] data = new double[3]; + mat.get(indices, data); + return new Tuple3(data[0], data[1], data[2]); + } + + @Override + public void setV3c(Tuple3 v) { + double[] data = new double[] { v._0, v._1, v._2 }; + mat.put(indices, data); + } + + @Override + public Tuple4 getV4c() { + double[] data = new double[4]; + mat.get(indices, data); + return new Tuple4(data[0], data[1], data[2], data[3]); + } + + @Override + public void setV4c(Tuple4 v) { + double[] data = new double[] { v._0, v._1, v._2, v._3 }; + mat.put(indices, data); + } + } + + private static class AtableFloat extends AtableBase implements Atable { + + public AtableFloat(Mat mat, int row, int col) { + super(mat, row, col); + } + + public AtableFloat(Mat mat, int[] indices) { + super(mat, indices); + } + + @Override + public Float getV() { + float[] data = new float[1]; + mat.get(indices, data); + return data[0]; + } + + @Override + public void setV(Float v) { + float[] data = new float[] { v }; + mat.put(indices, data); + } + + @Override + public Tuple2 getV2c() { + float[] data = new float[2]; + mat.get(indices, data); + return new Tuple2(data[0], data[1]); + } + + @Override + public void setV2c(Tuple2 v) { + float[] data = new float[] { v._0, v._1 }; + mat.put(indices, data); + } + + @Override + public Tuple3 getV3c() { + float[] data = new float[3]; + mat.get(indices, data); + return new Tuple3(data[0], data[1], data[2]); + } + + @Override + public void setV3c(Tuple3 v) { + float[] data = new float[] { v._0, v._1, v._2 }; + mat.put(indices, data); + } + + @Override + public Tuple4 getV4c() { + float[] data = new float[4]; + mat.get(indices, data); + return new Tuple4(data[0], data[1], data[2], data[3]); + } + + @Override + public void setV4c(Tuple4 v) { + double[] data = new double[] { v._0, v._1, v._2, v._3 }; + mat.put(indices, data); + } + } + + private static class AtableInteger extends AtableBase implements Atable { + + public AtableInteger(Mat mat, int row, int col) { + super(mat, row, col); + } + + public AtableInteger(Mat mat, int[] indices) { + super(mat, indices); + } + + @Override + public Integer getV() { + int[] data = new int[1]; + mat.get(indices, data); + return data[0]; + } + + @Override + public void setV(Integer v) { + int[] data = new int[] { v }; + mat.put(indices, data); + } + + @Override + public Tuple2 getV2c() { + int[] data = new int[2]; + mat.get(indices, data); + return new Tuple2(data[0], data[1]); + } + + @Override + public void setV2c(Tuple2 v) { + int[] data = new int[] { v._0, v._1 }; + mat.put(indices, data); + } + + @Override + public Tuple3 getV3c() { + int[] data = new int[3]; + mat.get(indices, data); + return new Tuple3(data[0], data[1], data[2]); + } + + @Override + public void setV3c(Tuple3 v) { + int[] data = new int[] { v._0, v._1, v._2 }; + mat.put(indices, data); + } + + @Override + public Tuple4 getV4c() { + int[] data = new int[4]; + mat.get(indices, data); + return new Tuple4(data[0], data[1], data[2], data[3]); + } + + @Override + public void setV4c(Tuple4 v) { + int[] data = new int[] { v._0, v._1, v._2, v._3 }; + mat.put(indices, data); + } + } + + private static class AtableShort extends AtableBase implements Atable { + + public AtableShort(Mat mat, int row, int col) { + super(mat, row, col); + } + + public AtableShort(Mat mat, int[] indices) { + super(mat, indices); + } + + @Override + public Short getV() { + short[] data = new short[1]; + mat.get(indices, data); + return data[0]; + } + + @Override + public void setV(Short v) { + short[] data = new short[] { v }; + mat.put(indices, data); + } + + @Override + public Tuple2 getV2c() { + short[] data = new short[2]; + mat.get(indices, data); + return new Tuple2(data[0], data[1]); + } + + @Override + public void setV2c(Tuple2 v) { + short[] data = new short[] { v._0, v._1 }; + mat.put(indices, data); + } + + @Override + public Tuple3 getV3c() { + short[] data = new short[3]; + mat.get(indices, data); + return new Tuple3(data[0], data[1], data[2]); + } + + @Override + public void setV3c(Tuple3 v) { + short[] data = new short[] { v._0, v._1, v._2 }; + mat.put(indices, data); + } + + @Override + public Tuple4 getV4c() { + short[] data = new short[4]; + mat.get(indices, data); + return new Tuple4(data[0], data[1], data[2], data[3]); + } + + @Override + public void setV4c(Tuple4 v) { + short[] data = new short[] { v._0, v._1, v._2, v._3 }; + mat.put(indices, data); + } + } + // javadoc:Mat::getNativeObjAddr() public long getNativeObjAddr() { return nativeObj; diff --git a/modules/core/misc/java/src/java/core+MatAt.kt b/modules/core/misc/java/src/java/core+MatAt.kt new file mode 100644 index 000000000000..c81e21057f27 --- /dev/null +++ b/modules/core/misc/java/src/java/core+MatAt.kt @@ -0,0 +1,160 @@ +package org.opencv.core + +import org.opencv.core.Mat.* +import java.lang.RuntimeException + +fun Mat.get(row: Int, col: Int, data: UByteArray) = this.get(row, col, data.asByteArray()) +fun Mat.get(indices: IntArray, data: UByteArray) = this.get(indices, data.asByteArray()) +fun Mat.put(row: Int, col: Int, data: UByteArray) = this.put(row, col, data.asByteArray()) +fun Mat.put(indices: IntArray, data: UByteArray) = this.put(indices, data.asByteArray()) + +fun Mat.get(row: Int, col: Int, data: UShortArray) = this.get(row, col, data.asShortArray()) +fun Mat.get(indices: IntArray, data: UShortArray) = this.get(indices, data.asShortArray()) +fun Mat.put(row: Int, col: Int, data: UShortArray) = this.put(row, col, data.asShortArray()) +fun Mat.put(indices: IntArray, data: UShortArray) = this.put(indices, data.asShortArray()) + +/*** + * Example use: + * + * val (b, g, r) = mat.at(50, 50).v3c + * mat.at(50, 50).val = T3(245u, 113u, 34u) + * + */ +@Suppress("UNCHECKED_CAST") +inline fun Mat.at(row: Int, col: Int) : Atable = + when (T::class) { + Byte::class, Double::class, Float::class, Int::class, Short::class -> this.at( + T::class.java, + row, + col + ) + UByte::class -> AtableUByte(this, row, col) as Atable + UShort::class -> AtableUShort(this, row, col) as Atable + else -> throw RuntimeException("Unsupported class type") + } + +@Suppress("UNCHECKED_CAST") +inline fun Mat.at(idx: IntArray) : Atable = + when (T::class) { + Byte::class, Double::class, Float::class, Int::class, Short::class -> this.at( + T::class.java, + idx + ) + UByte::class -> AtableUByte(this, idx) as Atable + UShort::class -> AtableUShort(this, idx) as Atable + else -> throw RuntimeException("Unsupported class type") + } + +class AtableUByte(val mat: Mat, val indices: IntArray): Atable { + + constructor(mat: Mat, row: Int, col: Int) : this(mat, intArrayOf(row, col)) + + override fun getV(): UByte { + val data = UByteArray(1) + mat.get(indices, data) + return data[0] + } + + override fun setV(v: UByte) { + val data = ubyteArrayOf(v) + mat.put(indices, data) + } + + override fun getV2c(): Tuple2 { + val data = UByteArray(2) + mat.get(indices, data) + return Tuple2(data[0], data[1]) + } + + override fun setV2c(v: Tuple2) { + val data = ubyteArrayOf(v._0, v._1) + mat.put(indices, data) + } + + override fun getV3c(): Tuple3 { + val data = UByteArray(3) + mat.get(indices, data) + return Tuple3(data[0], data[1], data[2]) + } + + override fun setV3c(v: Tuple3) { + val data = ubyteArrayOf(v._0, v._1, v._2) + mat.put(indices, data) + } + + override fun getV4c(): Tuple4 { + val data = UByteArray(4) + mat.get(indices, data) + return Tuple4(data[0], data[1], data[2], data[3]) + } + + override fun setV4c(v: Tuple4) { + val data = ubyteArrayOf(v._0, v._1, v._2, v._3) + mat.put(indices, data) + } +} + +class AtableUShort(val mat: Mat, val indices: IntArray): Atable { + + constructor(mat: Mat, row: Int, col: Int) : this(mat, intArrayOf(row, col)) + + override fun getV(): UShort { + val data = UShortArray(1) + mat.get(indices, data) + return data[0] + } + + override fun setV(v: UShort) { + val data = ushortArrayOf(v) + mat.put(indices, data) + } + + override fun getV2c(): Tuple2 { + val data = UShortArray(2) + mat.get(indices, data) + return Tuple2(data[0], data[1]) + } + + override fun setV2c(v: Tuple2) { + val data = ushortArrayOf(v._0, v._1) + mat.put(indices, data) + } + + override fun getV3c(): Tuple3 { + val data = UShortArray(3) + mat.get(indices, data) + return Tuple3(data[0], data[1], data[2]) + } + + override fun setV3c(v: Tuple3) { + val data = ushortArrayOf(v._0, v._1, v._2) + mat.put(indices, data) + } + + override fun getV4c(): Tuple4 { + val data = UShortArray(4) + mat.get(indices, data) + return Tuple4(data[0], data[1], data[2], data[3]) + } + + override fun setV4c(v: Tuple4) { + val data = ushortArrayOf(v._0, v._1, v._2, v._3) + mat.put(indices, data) + } +} + +operator fun Tuple2.component1(): T = this._0 +operator fun Tuple2.component2(): T = this._1 + +operator fun Tuple3.component1(): T = this._0 +operator fun Tuple3.component2(): T = this._1 +operator fun Tuple3.component3(): T = this._2 + +operator fun Tuple4.component1(): T = this._0 +operator fun Tuple4.component2(): T = this._1 +operator fun Tuple4.component3(): T = this._2 +operator fun Tuple4.component4(): T = this._3 + +fun T2(_0: T, _1: T) : Tuple2 = Tuple2(_0, _1) +fun T3(_0: T, _1: T, _2: T) : Tuple3 = Tuple3(_0, _1, _2) +fun T4(_0: T, _1: T, _2: T, _3: T) : Tuple4 = Tuple4(_0, _1, _2, _3) diff --git a/modules/core/misc/java/test/MatTest.java b/modules/core/misc/java/test/MatTest.java index 00e7b7cb3203..3075dba16b35 100644 --- a/modules/core/misc/java/test/MatTest.java +++ b/modules/core/misc/java/test/MatTest.java @@ -1285,4 +1285,31 @@ public void testMatFromByteBufferWithStep() { assertEquals(5, bbuf.get(63*80 + 63)); } + public void testMatAt() { + Mat uc1 = new Mat(2, 3, CvType.CV_8S) { + { + put(0, 0, 1, 2, 3); + put(1, 0, 4, 5, 6); + } + }; + assertEquals((byte)1, uc1.at(Byte.class, 0, 0).getV().byteValue()); + assertEquals((byte)2, uc1.at(Byte.class, 0, 1).getV().byteValue()); + assertEquals((byte)3, uc1.at(Byte.class, 0, 2).getV().byteValue()); + assertEquals((byte)4, uc1.at(Byte.class, 1, 0).getV().byteValue()); + assertEquals((byte)5, uc1.at(Byte.class, 1, 1).getV().byteValue()); + assertEquals((byte)6, uc1.at(Byte.class, 1, 2).getV().byteValue()); + uc1.at(Byte.class, 0, 0).setV((byte)7); + uc1.at(Byte.class, 0, 1).setV((byte)8); + uc1.at(Byte.class, 0, 2).setV((byte)9); + uc1.at(Byte.class, 1, 0).setV((byte)10); + uc1.at(Byte.class, 1, 1).setV((byte)11); + uc1.at(Byte.class, 1, 2).setV((byte)12); + byte[] data = new byte[6]; + uc1.get(0, 0, data); + assertArrayEquals(data, new byte[] {7, 8, 9, 10, 11, 12}); + Mat.Tuple3 bgr = rgbLena.at(Byte.class, 0, 0).getV3c(); + assertEquals(bgr.get_0().byteValue(), (byte)128); + assertEquals(bgr.get_1().byteValue(), (byte)138); + assertEquals(bgr.get_2().byteValue(), (byte)225); + } } diff --git a/modules/core/misc/objc/common/Mat.mm b/modules/core/misc/objc/common/Mat.mm index 5d41a3622e71..045bd8393ea3 100644 --- a/modules/core/misc/objc/common/Mat.mm +++ b/modules/core/misc/objc/common/Mat.mm @@ -548,7 +548,7 @@ - (void)put:(uchar*)dest data:(NSArray*)data offset:(int)offset count if (depth == CV_8U) { putData(dest, count, ^uchar (int index) { return cv::saturate_cast(data[offset + index].doubleValue);} ); } else if (depth == CV_8S) { - putData(dest, count, ^char (int index) { return cv::saturate_cast(data[offset + index].doubleValue);} ); + putData(dest, count, ^schar (int index) { return cv::saturate_cast(data[offset + index].doubleValue);} ); } else if (depth == CV_16U) { putData(dest, count, ^ushort (int index) { return cv::saturate_cast(data[offset + index].doubleValue);} ); } else if (depth == CV_16S) { diff --git a/modules/core/misc/objc/common/MatExt.swift b/modules/core/misc/objc/common/MatExt.swift index f6b3072345ec..a6ba548599d8 100644 --- a/modules/core/misc/objc/common/MatExt.swift +++ b/modules/core/misc/objc/common/MatExt.swift @@ -33,6 +33,10 @@ func throwIncompatibleBufferSize(count: Int, channels: Int32) throws { ) } +public typealias T2 = (T, T) +public typealias T3 = (T, T, T) +public typealias T4 = (T, T, T, T) + public extension Mat { convenience init(rows:Int32, cols:Int32, type:Int32, data:[Int8]) { @@ -58,6 +62,21 @@ public extension Mat { } } + @discardableResult func get(indices:[Int32], data:inout [UInt8]) throws -> Int32 { + let channels = CvType.channels(Int32(type())) + if Int32(data.count) % channels != 0 { + try throwIncompatibleBufferSize(count: data.count, channels: channels) + } else if depth() != CvType.CV_8U { + try throwIncompatibleDataType(typeName: CvType.type(toString: type())) + } + let count = Int32(data.count) + return data.withUnsafeMutableBufferPointer { body in + body.withMemoryRebound(to: Int8.self) { reboundBody in + return __get(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!) + } + } + } + @discardableResult func get(indices:[Int32], data:inout [Double]) throws -> Int32 { let channels = CvType.channels(Int32(type())) if Int32(data.count) % channels != 0 { @@ -110,10 +129,29 @@ public extension Mat { } } + @discardableResult func get(indices:[Int32], data:inout [UInt16]) throws -> Int32 { + let channels = CvType.channels(Int32(type())) + if Int32(data.count) % channels != 0 { + try throwIncompatibleBufferSize(count: data.count, channels: channels) + } else if depth() != CvType.CV_16U { + try throwIncompatibleDataType(typeName: CvType.type(toString: type())) + } + let count = Int32(data.count) + return data.withUnsafeMutableBufferPointer { body in + body.withMemoryRebound(to: Int16.self) { reboundBody in + return __get(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!) + } + } + } + @discardableResult func get(row: Int32, col: Int32, data:inout [Int8]) throws -> Int32 { return try get(indices: [row, col], data: &data) } + @discardableResult func get(row: Int32, col: Int32, data:inout [UInt8]) throws -> Int32 { + return try get(indices: [row, col], data: &data) + } + @discardableResult func get(row: Int32, col: Int32, data:inout [Double]) throws -> Int32 { return try get(indices: [row, col], data: &data) } @@ -130,6 +168,10 @@ public extension Mat { return try get(indices: [row, col], data: &data) } + @discardableResult func get(row: Int32, col: Int32, data:inout [UInt16]) throws -> Int32 { + return try get(indices: [row, col], data: &data) + } + @discardableResult func put(indices:[Int32], data:[Int8]) throws -> Int32 { let channels = CvType.channels(Int32(type())) if Int32(data.count) % channels != 0 { @@ -143,6 +185,21 @@ public extension Mat { } } + @discardableResult func put(indices:[Int32], data:[UInt8]) throws -> Int32 { + let channels = CvType.channels(Int32(type())) + if Int32(data.count) % channels != 0 { + try throwIncompatibleBufferSize(count: data.count, channels: channels) + } else if depth() != CvType.CV_8U { + try throwIncompatibleDataType(typeName: CvType.type(toString: type())) + } + let count = Int32(data.count) + return data.withUnsafeBufferPointer { body in + body.withMemoryRebound(to: Int8.self) { reboundBody in + return __put(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!) + } + } + } + @discardableResult func put(indices:[Int32], data:[Int8], offset: Int, length: Int32) throws -> Int32 { let channels = CvType.channels(Int32(type())) if Int32(data.count) % channels != 0 { @@ -210,10 +267,29 @@ public extension Mat { } } + @discardableResult func put(indices:[Int32], data:[UInt16]) throws -> Int32 { + let channels = CvType.channels(Int32(type())) + if Int32(data.count) % channels != 0 { + try throwIncompatibleBufferSize(count: data.count, channels: channels) + } else if depth() != CvType.CV_16U { + try throwIncompatibleDataType(typeName: CvType.type(toString: type())) + } + let count = Int32(data.count) + return data.withUnsafeBufferPointer { body in + body.withMemoryRebound(to: Int16.self) { reboundBody in + return __put(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!) + } + } + } + @discardableResult func put(row: Int32, col: Int32, data:[Int8]) throws -> Int32 { return try put(indices: [row, col], data: data) } + @discardableResult func put(row: Int32, col: Int32, data:[UInt8]) throws -> Int32 { + return try put(indices: [row, col], data: data) + } + @discardableResult func put(row: Int32, col: Int32, data: [Int8], offset: Int, length: Int32) throws -> Int32 { return try put(indices: [row, col], data: data, offset: offset, length: length) } @@ -234,6 +310,10 @@ public extension Mat { return try put(indices: [row, col], data: data) } + @discardableResult func put(row: Int32, col: Int32, data: [UInt16]) throws -> Int32 { + return try put(indices: [row, col], data: data) + } + @discardableResult func get(row: Int32, col: Int32) -> [Double] { return get(indices: [row, col]) } @@ -242,3 +322,396 @@ public extension Mat { return __get(indices as [NSNumber]) as! [Double] } } + +public protocol Atable { + static func getAt(m: Mat, indices:[Int32]) -> Self + static func putAt(m: Mat, indices:[Int32], v: Self) + static func getAt2c(m: Mat, indices:[Int32]) -> (Self, Self) + static func putAt2c(m: Mat, indices:[Int32], v: (Self, Self)) + static func getAt3c(m: Mat, indices:[Int32]) -> (Self, Self, Self) + static func putAt3c(m: Mat, indices:[Int32], v: (Self, Self, Self)) + static func getAt4c(m: Mat, indices:[Int32]) -> (Self, Self, Self, Self) + static func putAt4c(m: Mat, indices:[Int32], v: (Self, Self, Self, Self)) +} + +public class MatAt { + + init(mat: Mat, indices: [Int32]) { + self.mat = mat + self.indices = indices + } + + private let mat: Mat + private let indices: [Int32] + public var v: N { + get { + return N.getAt(m: mat, indices: indices) + } + set(value) { + N.putAt(m: mat, indices: indices, v: value) + } + } + public var v2c: (N, N) { + get { + return N.getAt2c(m: mat, indices: indices) + } + set(value) { + N.putAt2c(m: mat, indices: indices, v: value) + } + } + public var v3c: (N, N, N) { + get { + return N.getAt3c(m: mat, indices: indices) + } + set(value) { + N.putAt3c(m: mat, indices: indices, v: value) + } + } + public var v4c: (N, N, N, N) { + get { + return N.getAt4c(m: mat, indices: indices) + } + set(value) { + N.putAt4c(m: mat, indices: indices, v: value) + } + } +} + +extension UInt8: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> UInt8 { + var tmp = [UInt8](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: UInt8) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt8, UInt8) { + var tmp = [UInt8](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (UInt8, UInt8)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8) { + var tmp = [UInt8](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8, UInt8) { + var tmp = [UInt8](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8, UInt8)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Int8: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Int8 { + var tmp = [Int8](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Int8) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Int8, Int8) { + var tmp = [Int8](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Int8, Int8)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Int8, Int8, Int8) { + var tmp = [Int8](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Int8, Int8, Int8)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Int8, Int8, Int8, Int8) { + var tmp = [Int8](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Int8, Int8, Int8, Int8)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Double: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Double { + var tmp = [Double](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Double) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Double, Double) { + var tmp = [Double](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Double, Double)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Double, Double, Double) { + var tmp = [Double](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Double, Double, Double)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Double, Double, Double, Double) { + var tmp = [Double](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Double, Double, Double, Double)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Float: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Float { + var tmp = [Float](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Float) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Float, Float) { + var tmp = [Float](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Float, Float)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Float, Float, Float) { + var tmp = [Float](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Float, Float, Float)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Float, Float, Float, Float) { + var tmp = [Float](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Float, Float, Float, Float)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Int32: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Int32 { + var tmp = [Int32](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Int32) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Int32, Int32) { + var tmp = [Int32](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Int32, Int32)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Int32, Int32, Int32) { + var tmp = [Int32](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Int32, Int32, Int32)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Int32, Int32, Int32, Int32) { + var tmp = [Int32](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Int32, Int32, Int32, Int32)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension UInt16: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> UInt16 { + var tmp = [UInt16](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: UInt16) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt16, UInt16) { + var tmp = [UInt16](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (UInt16, UInt16)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16) { + var tmp = [UInt16](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (UInt16, UInt16, UInt16)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16, UInt16) { + var tmp = [UInt16](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (UInt16, UInt16, UInt16, UInt16)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +extension Int16: Atable { + public static func getAt(m: Mat, indices:[Int32]) -> Int16 { + var tmp = [Int16](repeating: 0, count: 1) + try! m.get(indices: indices, data: &tmp) + return tmp[0] + } + + public static func putAt(m: Mat, indices: [Int32], v: Int16) { + let tmp = [v] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt2c(m: Mat, indices:[Int32]) -> (Int16, Int16) { + var tmp = [Int16](repeating: 0, count: 2) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1]) + } + + public static func putAt2c(m: Mat, indices: [Int32], v: (Int16, Int16)) { + let tmp = [v.0, v.1] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt3c(m: Mat, indices:[Int32]) -> (Int16, Int16, Int16) { + var tmp = [Int16](repeating: 0, count: 3) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2]) + } + + public static func putAt3c(m: Mat, indices: [Int32], v: (Int16, Int16, Int16)) { + let tmp = [v.0, v.1, v.2] + try! m.put(indices: indices, data: tmp) + } + + public static func getAt4c(m: Mat, indices:[Int32]) -> (Int16, Int16, Int16, Int16) { + var tmp = [Int16](repeating: 0, count: 4) + try! m.get(indices: indices, data: &tmp) + return (tmp[0], tmp[1], tmp[2], tmp[3]) + } + + public static func putAt4c(m: Mat, indices: [Int32], v: (Int16, Int16, Int16, Int16)) { + let tmp = [v.0, v.1, v.2, v.3] + try! m.put(indices: indices, data: tmp) + } +} + +/*** + * Example use: + * + * let elemantVal: UInt8 = mat.at(row: 50, col: 50).v + * mat.at(row: 50, col: 50).v = 245 + * + */ +public extension Mat { + func at(row: Int32, col: Int32) -> MatAt { + return MatAt(mat: self, indices: [row, col]) + } + + func at(indices:[Int32]) -> MatAt { + return MatAt(mat: self, indices: indices) + } +} diff --git a/modules/core/misc/objc/test/MatTest.swift b/modules/core/misc/objc/test/MatTest.swift index af26eb0bdb20..8a513505cc14 100644 --- a/modules/core/misc/objc/test/MatTest.swift +++ b/modules/core/misc/objc/test/MatTest.swift @@ -308,15 +308,15 @@ class MatTests: OpenCVTestCase { XCTAssert([340] == sm.get(row: 1, col: 1)) } - func testGetIntIntByteArray() throws { - let m = try getTestMat(size: 5, type: CvType.CV_8UC3) + func testGetIntIntInt8Array() throws { + let m = try getTestMat(size: 5, type: CvType.CV_8SC3) var goodData = [Int8](repeating: 0, count: 9) // whole Mat var bytesNum = try m.get(row: 1, col: 1, data: &goodData) XCTAssertEqual(9, bytesNum) - XCTAssert([110, 111, 112, 120, 121, 122, -126, -125, -124] == goodData) + XCTAssert([110, 111, 112, 120, 121, 122, 127, 127, 127] == goodData) var badData = [Int8](repeating: 0, count: 7) XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData)) @@ -326,11 +326,36 @@ class MatTests: OpenCVTestCase { var buff00 = [Int8](repeating: 0, count: 3) bytesNum = try sm.get(row: 0, col: 0, data: &buff00) XCTAssertEqual(3, bytesNum) - XCTAssert(buff00 == [-26, -25, -24]) + XCTAssert(buff00 == [127, 127, 127]) var buff11 = [Int8](repeating: 0, count: 3) bytesNum = try sm.get(row: 1, col: 1, data: &buff11) XCTAssertEqual(3, bytesNum) - XCTAssert(buff11 == [-1, -1, -1]) + XCTAssert(buff11 == [127, 127, 127]) + } + + func testGetIntIntUInt8Array() throws { + let m = try getTestMat(size: 5, type: CvType.CV_8UC3) + var goodData = [UInt8](repeating: 0, count: 9) + + // whole Mat + var bytesNum = try m.get(row: 1, col: 1, data: &goodData) + + XCTAssertEqual(9, bytesNum) + XCTAssert([110, 111, 112, 120, 121, 122, 130, 131, 132] == goodData) + + var badData = [UInt8](repeating: 0, count: 7) + XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData)) + + // sub-Mat + let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5) + var buff00 = [UInt8](repeating: 0, count: 3) + bytesNum = try sm.get(row: 0, col: 0, data: &buff00) + XCTAssertEqual(3, bytesNum) + XCTAssert(buff00 == [230, 231, 232]) + var buff11 = [UInt8](repeating: 0, count: 3) + bytesNum = try sm.get(row: 1, col: 1, data: &buff11) + XCTAssertEqual(3, bytesNum) + XCTAssert(buff11 == [255, 255, 255]) } func testGetIntIntDoubleArray() throws { @@ -399,7 +424,7 @@ class MatTests: OpenCVTestCase { XCTAssert(buff11 == [340, 341, 0, 0]) } - func testGetIntIntShortArray() throws { + func testGetIntIntInt16Array() throws { let m = try getTestMat(size: 5, type: CvType.CV_16SC2) var buff = [Int16](repeating: 0, count: 6) @@ -421,6 +446,28 @@ class MatTests: OpenCVTestCase { XCTAssert(buff11 == [340, 341, 0, 0]) } + func testGetIntIntUInt16Array() throws { + let m = try getTestMat(size: 5, type: CvType.CV_16UC2) + var buff = [UInt16](repeating: 0, count: 6) + + // whole Mat + var bytesNum = try m.get(row: 1, col: 1, data: &buff) + + XCTAssertEqual(12, bytesNum); + XCTAssert(buff == [110, 111, 120, 121, 130, 131]) + + // sub-Mat + let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5) + var buff00 = [UInt16](repeating: 0, count: 4) + bytesNum = try sm.get(row: 0, col: 0, data: &buff00) + XCTAssertEqual(8, bytesNum) + XCTAssert(buff00 == [230, 231, 240, 241]) + var buff11 = [UInt16](repeating: 0, count: 4) + bytesNum = try sm.get(row: 1, col: 1, data: &buff11) + XCTAssertEqual(4, bytesNum); + XCTAssert(buff11 == [340, 341, 0, 0]) + } + func testHeight() { XCTAssertEqual(gray0.rows(), gray0.height()) XCTAssertEqual(rgbLena.rows(), rgbLena.height()) @@ -653,7 +700,7 @@ class MatTests: OpenCVTestCase { try assertMatEqual(truth!, m1, OpenCVTestCase.EPS) } - func testPutIntIntByteArray() throws { + func testPutIntIntInt8Array() throws { let m = Mat(rows: 5, cols: 5, type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3)) let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5) var buff = [Int8](repeating: 0, count: 6) @@ -683,7 +730,37 @@ class MatTests: OpenCVTestCase { XCTAssert(buff == buff0) } - func testPutIntArrayByteArray() throws { + func testPutIntIntUInt8Array() throws { + let m = Mat(rows: 5, cols: 5, type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3)) + let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5) + var buff = [UInt8](repeating: 0, count: 6) + let buff0:[UInt8] = [10, 20, 30, 40, 50, 60] + let buff1:[UInt8] = [255, 254, 253, 252, 251, 250] + + var bytesNum = try m.put(row:1, col:2, data:buff0) + + XCTAssertEqual(6, bytesNum) + bytesNum = try m.get(row: 1, col: 2, data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff0) + + bytesNum = try sm.put(row:0, col:0, data:buff1) + + XCTAssertEqual(6, bytesNum) + bytesNum = try sm.get(row: 0, col: 0, data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff1) + bytesNum = try m.get(row: 2, col: 3, data: &buff) + XCTAssertEqual(6, bytesNum); + XCTAssert(buff == buff1) + + let m1 = m.row(1) + bytesNum = try m1.get(row: 0, col: 2, data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff0) + } + + func testPutIntArrayInt8Array() throws { let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3)) let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)]) var buff = [Int8](repeating: 0, count: 6) @@ -714,10 +791,41 @@ class MatTests: OpenCVTestCase { XCTAssert(buff == buff0) } + func testPutIntArrayUInt8Array() throws { + let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3)) + let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)]) + var buff = [UInt8](repeating: 0, count: 6) + let buff0:[UInt8] = [10, 20, 30, 40, 50, 60] + let buff1:[UInt8] = [255, 254, 253, 252, 251, 250] + + var bytesNum = try m.put(indices:[1, 2, 0], data:buff0) + + XCTAssertEqual(6, bytesNum) + bytesNum = try m.get(indices: [1, 2, 0], data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff0) + + bytesNum = try sm.put(indices: [0, 0, 0], data: buff1) + + XCTAssertEqual(6, bytesNum) + bytesNum = try sm.get(indices: [0, 0, 0], data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff1) + + bytesNum = try m.get(indices: [0, 1, 2], data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff1) + + let m1 = m.submat(ranges: [Range(start: 1,end: 2), Range.all(), Range.all()]) + bytesNum = try m1.get(indices: [0, 2, 0], data: &buff) + XCTAssertEqual(6, bytesNum) + XCTAssert(buff == buff0) + } + func testPutIntIntDoubleArray() throws { - let m = Mat(rows: 5, cols: 5, type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3)) + let m = Mat(rows: 5, cols: 5, type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3)) let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5) - var buff = [Int8](repeating: 0, count: 6) + var buff = [UInt8](repeating: 0, count: 6) var bytesNum = try m.put(row: 1, col: 2, data: [10, 20, 30, 40, 50, 60] as [Double]) @@ -731,16 +839,16 @@ class MatTests: OpenCVTestCase { XCTAssertEqual(6, bytesNum) bytesNum = try sm.get(row: 0, col: 0, data: &buff) XCTAssertEqual(6, bytesNum); - XCTAssert(buff == [-1, -2, -3, -4, -5, -6]) + XCTAssert(buff == [255, 254, 253, 252, 251, 250]) bytesNum = try m.get(row: 2, col: 3, data: &buff) XCTAssertEqual(6, bytesNum); - XCTAssert(buff == [-1, -2, -3, -4, -5, -6]) + XCTAssert(buff == [255, 254, 253, 252, 251, 250]) } func testPutIntArrayDoubleArray() throws { - let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3)) + let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3)) let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)]) - var buff = [Int8](repeating: 0, count: 6) + var buff = [UInt8](repeating: 0, count: 6) var bytesNum = try m.put(indices: [1, 2, 0], data: [10, 20, 30, 40, 50, 60] as [Double]) @@ -754,10 +862,10 @@ class MatTests: OpenCVTestCase { XCTAssertEqual(6, bytesNum); bytesNum = try sm.get(indices: [0, 0, 0], data: &buff) XCTAssertEqual(6, bytesNum); - XCTAssert(buff == [-1, -2, -3, -4, -5, -6]) + XCTAssert(buff == [255, 254, 253, 252, 251, 250]) bytesNum = try m.get(indices: [0, 1, 2], data: &buff) XCTAssertEqual(6, bytesNum) - XCTAssert(buff == [-1, -2, -3, -4, -5, -6]) + XCTAssert(buff == [255, 254, 253, 252, 251, 250]) } func testPutIntIntFloatArray() throws { @@ -820,7 +928,7 @@ class MatTests: OpenCVTestCase { XCTAssert([40, 50, 60] == m.get(indices: [0, 1, 0])) } - func testPutIntIntShortArray() throws { + func testPutIntIntInt16Array() throws { let m = Mat(rows: 5, cols: 5, type: CvType.CV_16SC3, scalar: Scalar(-1, -2, -3)) let elements: [Int16] = [ 10, 20, 30, 40, 50, 60] @@ -834,7 +942,21 @@ class MatTests: OpenCVTestCase { XCTAssert([40, 50, 60] == m.get(row: 2, col: 4)) } - func testPutIntArrayShortArray() throws { + func testPutIntIntUInt16Array() throws { + let m = Mat(rows: 5, cols: 5, type: CvType.CV_16UC3, scalar: Scalar(-1, -2, -3)) + let elements: [UInt16] = [ 10, 20, 30, 40, 50, 60] + + var bytesNum = try m.put(row: 2, col: 3, data: elements) + + XCTAssertEqual(Int32(elements.count * 2), bytesNum) + let m1 = m.col(3) + var buff = [UInt16](repeating: 0, count: 3) + bytesNum = try m1.get(row: 2, col: 0, data: &buff) + XCTAssert(buff == [10, 20, 30]) + XCTAssert([40, 50, 60] == m.get(row: 2, col: 4)) + } + + func testPutIntArrayInt16Array() throws { let m = Mat(sizes: [5, 5, 5], type: CvType.CV_16SC3, scalar: Scalar(-1, -2, -3)) let elements: [Int16] = [ 10, 20, 30, 40, 50, 60] @@ -848,6 +970,20 @@ class MatTests: OpenCVTestCase { XCTAssert([40, 50, 60] == m.get(indices: [0, 2, 4])) } + func testPutIntArrayUInt16Array() throws { + let m = Mat(sizes: [5, 5, 5], type: CvType.CV_16UC3, scalar: Scalar(-1, -2, -3)) + let elements: [UInt16] = [ 10, 20, 30, 40, 50, 60] + + var bytesNum = try m.put(indices: [0, 2, 3], data: elements) + + XCTAssertEqual(Int32(elements.count * 2), bytesNum) + let m1 = m.submat(ranges: [Range.all(), Range.all(), Range(start: 3, end: 4)]) + var buff = [UInt16](repeating: 0, count: 3) + bytesNum = try m1.get(indices: [0, 2, 0], data: &buff) + XCTAssert(buff == [10, 20, 30]) + XCTAssert([40, 50, 60] == m.get(indices: [0, 2, 4])) + } + func testReshapeInt() throws { let src = Mat(rows: 4, cols: 4, type: CvType.CV_8U, scalar: Scalar(0)) dst = src.reshape(channels: 4) @@ -1143,4 +1279,28 @@ class MatTests: OpenCVTestCase { XCTAssertEqual(5, bufferOut[63*80 + 63]) } + func testMatAt() { + let uc1 = Mat(rows: 2, cols: 3, type: CvType.CV_8U) + try! uc1.put(row: 0, col: 0, data: [1, 2, 3, 4, 5, 6] as [Int8]) + XCTAssertEqual(UInt8(1), uc1.at(row: 0, col: 0).v) + XCTAssertEqual(UInt8(2), uc1.at(row: 0, col: 1).v) + XCTAssertEqual(UInt8(3), uc1.at(row: 0, col: 2).v) + XCTAssertEqual(UInt8(4), uc1.at(row: 1, col: 0).v) + XCTAssertEqual(UInt8(5), uc1.at(row: 1, col: 1).v) + XCTAssertEqual(UInt8(6), uc1.at(row: 1, col: 2).v) + uc1.at(row: 0, col: 0).v = UInt8(7) + uc1.at(row: 0, col: 1).v = UInt8(8) + uc1.at(row: 0, col: 2).v = UInt8(9) + uc1.at(row: 1, col: 0).v = UInt8(10) + uc1.at(row: 1, col: 1).v = UInt8(11) + uc1.at(row: 1, col: 2).v = UInt8(12) + var data = [Int8](repeating: 0, count: 6) + try! uc1.get(row: 0, col: 0, data: &data) + XCTAssertEqual(data, [7, 8, 9, 10, 11, 12] as [Int8]) + let (b, g, r): T3 = rgbLena.at(row: 0, col: 0).v3c + XCTAssertEqual(b, UInt8(128)) + XCTAssertEqual(g, UInt8(138)) + XCTAssertEqual(r, UInt8(225)) + } + } diff --git a/modules/core/perf/opencl/perf_usage_flags.cpp b/modules/core/perf/opencl/perf_usage_flags.cpp index d59087121f51..0717121d1cf7 100644 --- a/modules/core/perf/opencl/perf_usage_flags.cpp +++ b/modules/core/perf/opencl/perf_usage_flags.cpp @@ -12,25 +12,33 @@ namespace opencv_test { namespace ocl { -typedef TestBaseWithParam > UsageFlagsBoolFixture; - -OCL_PERF_TEST_P(UsageFlagsBoolFixture, UsageFlags_AllocHostMem, ::testing::Combine(OCL_TEST_SIZES, Bool())) +typedef TestBaseWithParam> SizeUsageFlagsFixture; + +OCL_PERF_TEST_P(SizeUsageFlagsFixture, UsageFlags_AllocMem, + ::testing::Combine( + OCL_TEST_SIZES, + testing::Values(USAGE_DEFAULT, USAGE_ALLOCATE_HOST_MEMORY, USAGE_ALLOCATE_DEVICE_MEMORY), // USAGE_ALLOCATE_SHARED_MEMORY + testing::Values(USAGE_DEFAULT, USAGE_ALLOCATE_HOST_MEMORY, USAGE_ALLOCATE_DEVICE_MEMORY), // USAGE_ALLOCATE_SHARED_MEMORY + testing::Values(USAGE_DEFAULT, USAGE_ALLOCATE_HOST_MEMORY, USAGE_ALLOCATE_DEVICE_MEMORY) // USAGE_ALLOCATE_SHARED_MEMORY + )) { Size sz = get<0>(GetParam()); - bool allocHostMem = get<1>(GetParam()); + UMatUsageFlags srcAllocMem = get<1>(GetParam()); + UMatUsageFlags dstAllocMem = get<2>(GetParam()); + UMatUsageFlags finalAllocMem = get<3>(GetParam()); - UMat src(sz, CV_8UC1, Scalar::all(128)); + UMat src(sz, CV_8UC1, Scalar::all(128), srcAllocMem); OCL_TEST_CYCLE() { - UMat dst(allocHostMem ? USAGE_ALLOCATE_HOST_MEMORY : USAGE_DEFAULT); + UMat dst(dstAllocMem); cv::add(src, Scalar::all(1), dst); { Mat canvas = dst.getMat(ACCESS_RW); cv::putText(canvas, "Test", Point(20, 20), FONT_HERSHEY_PLAIN, 1, Scalar::all(255)); } - UMat final; + UMat final(finalAllocMem); cv::subtract(dst, Scalar::all(1), final); } diff --git a/modules/core/src/arithm.simd.hpp b/modules/core/src/arithm.simd.hpp index 0cddc909985c..f88597aacc68 100644 --- a/modules/core/src/arithm.simd.hpp +++ b/modules/core/src/arithm.simd.hpp @@ -1910,4 +1910,4 @@ DEFINE_SIMD_ALL(recip, recip_loop) #define SIMD_GUARD #endif -}} // cv::hal:: \ No newline at end of file +}} // cv::hal:: diff --git a/modules/core/src/async.cpp b/modules/core/src/async.cpp index a2f4612365b9..78c0a1ee8116 100644 --- a/modules/core/src/async.cpp +++ b/modules/core/src/async.cpp @@ -14,6 +14,7 @@ #define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG + 1 #include +#ifndef OPENCV_DISABLE_THREAD_SUPPORT #ifdef CV_CXX11 #include @@ -236,6 +237,171 @@ struct AsyncArray::Impl } }; +} // namespace + +#else // OPENCV_DISABLE_THREAD_SUPPORT + +namespace cv { + +// no threading +struct AsyncArray::Impl +{ + int refcount; + void addrefFuture() CV_NOEXCEPT { refcount_future++; refcount++; } + void releaseFuture() CV_NOEXCEPT { refcount_future--; if (0 == --refcount) delete this; } + int refcount_future; + void addrefPromise() CV_NOEXCEPT { refcount_promise++; refcount++; } \ + void releasePromise() CV_NOEXCEPT { refcount_promise--; if (0 == --refcount) delete this; } + int refcount_promise; + + mutable bool has_result; // Mat, UMat or exception + + mutable cv::Ptr result_mat; + mutable cv::Ptr result_umat; + + + bool has_exception; +#if CV__EXCEPTION_PTR + std::exception_ptr exception; +#endif + cv::Exception cv_exception; + + mutable bool result_is_fetched; + + bool future_is_returned; + + Impl() + : refcount(1), refcount_future(0), refcount_promise(1) + , has_result(false) + , has_exception(false) + , result_is_fetched(false) + , future_is_returned(false) + { + // nothing + } + + ~Impl() + { + if (has_result && !result_is_fetched) + { + CV_LOG_INFO(NULL, "Asynchronous result has not been fetched"); + } + } + + bool get(OutputArray dst, int64 timeoutNs) const + { + CV_Assert(!result_is_fetched); + if (!has_result) + { + CV_UNUSED(timeoutNs); + CV_Error(Error::StsError, "Result is not produced (unable to wait for result in OPENCV_DISABLE_THREAD_SUPPORT mode)"); + } + if (!result_mat.empty()) + { + dst.move(*result_mat.get()); + result_mat.release(); + result_is_fetched = true; + return true; + } + if (!result_umat.empty()) + { + dst.move(*result_umat.get()); + result_umat.release(); + result_is_fetched = true; + return true; + } +#if CV__EXCEPTION_PTR + if (has_exception && exception) + { + result_is_fetched = true; + std::rethrow_exception(exception); + } +#endif + if (has_exception) + { + result_is_fetched = true; + throw cv_exception; + } + CV_Error(Error::StsInternal, "AsyncArray: invalid state of 'has_result = true'"); + return false; + } + + bool valid() const CV_NOEXCEPT + { + if (result_is_fetched) + return false; + if (refcount_promise == 0 && !has_result) + return false; + return true; + } + + bool wait_for(int64 timeoutNs) const + { + CV_Assert(valid()); + if (has_result) + return has_result; + if (timeoutNs == 0) + return has_result; + CV_Error(Error::StsError, "Unable to wait in OPENCV_DISABLE_THREAD_SUPPORT mode"); + } + + AsyncArray getArrayResult() + { + CV_Assert(refcount_future == 0); + AsyncArray result; + addrefFuture(); + result.p = this; + future_is_returned = true; + return result; + } + + void setValue(InputArray value) + { + if (future_is_returned && refcount_future == 0) + CV_Error(Error::StsError, "Associated AsyncArray has been destroyed"); + CV_Assert(!has_result); + int k = value.kind(); + if (k == _InputArray::UMAT) + { + result_umat = makePtr(); + value.copyTo(*result_umat.get()); + } + else + { + result_mat = makePtr(); + value.copyTo(*result_mat.get()); + } + has_result = true; + } + +#if CV__EXCEPTION_PTR + void setException(std::exception_ptr e) + { + if (future_is_returned && refcount_future == 0) + CV_Error(Error::StsError, "Associated AsyncArray has been destroyed"); + CV_Assert(!has_result); + has_exception = true; + exception = e; + has_result = true; + } +#endif + + void setException(const cv::Exception e) + { + if (future_is_returned && refcount_future == 0) + CV_Error(Error::StsError, "Associated AsyncArray has been destroyed"); + CV_Assert(!has_result); + has_exception = true; + cv_exception = e; + has_result = true; + } +}; + +} + +#endif // OPENCV_DISABLE_THREAD_SUPPORT + +namespace cv { AsyncArray::AsyncArray() CV_NOEXCEPT : p(NULL) diff --git a/modules/core/src/directx.cpp b/modules/core/src/directx.cpp index d17adc6b48ae..2dbc3e27635e 100644 --- a/modules/core/src/directx.cpp +++ b/modules/core/src/directx.cpp @@ -80,15 +80,15 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) case DXGI_FORMAT_R32G32B32_UINT: case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3; //case DXGI_FORMAT_R16G16B16A16_TYPELESS: - //case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_FLOAT: return CV_16FC4; case DXGI_FORMAT_R16G16B16A16_UNORM: case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4; case DXGI_FORMAT_R16G16B16A16_SNORM: case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4; //case DXGI_FORMAT_R32G32_TYPELESS: - //case DXGI_FORMAT_R32G32_FLOAT: - //case DXGI_FORMAT_R32G32_UINT: - //case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G32_FLOAT: return CV_32FC2; + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: return CV_32SC2; //case DXGI_FORMAT_R32G8X24_TYPELESS: //case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: @@ -104,13 +104,13 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) case DXGI_FORMAT_R8G8B8A8_SNORM: case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4; //case DXGI_FORMAT_R16G16_TYPELESS: - //case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_FLOAT: return CV_16FC2; case DXGI_FORMAT_R16G16_UNORM: case DXGI_FORMAT_R16G16_UINT: return CV_16UC2; case DXGI_FORMAT_R16G16_SNORM: case DXGI_FORMAT_R16G16_SINT: return CV_16SC2; //case DXGI_FORMAT_R32_TYPELESS: - //case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_D32_FLOAT: case DXGI_FORMAT_R32_FLOAT: return CV_32FC1; case DXGI_FORMAT_R32_UINT: case DXGI_FORMAT_R32_SINT: return CV_32SC1; @@ -124,7 +124,7 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) case DXGI_FORMAT_R8G8_SNORM: case DXGI_FORMAT_R8G8_SINT: return CV_8SC2; //case DXGI_FORMAT_R16_TYPELESS: - //case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_R16_FLOAT: return CV_16FC1; case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UINT: return CV_16UC1; @@ -138,8 +138,8 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) case DXGI_FORMAT_A8_UNORM: return CV_8UC1; //case DXGI_FORMAT_R1_UNORM: //case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - //case DXGI_FORMAT_R8G8_B8G8_UNORM: - //case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: return CV_8UC4; //case DXGI_FORMAT_BC1_TYPELESS: //case DXGI_FORMAT_BC1_UNORM: //case DXGI_FORMAT_BC1_UNORM_SRGB: diff --git a/modules/core/src/dxt.cpp b/modules/core/src/dxt.cpp index 87873666d910..ab42a40a4428 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -40,7 +40,7 @@ //M*/ #include "precomp.hpp" -#include "opencv2/core/opencl/runtime/opencl_clamdfft.hpp" +#include "opencv2/core/opencl/runtime/opencl_clfft.hpp" #include "opencv2/core/opencl/runtime/opencl_core.hpp" #include "opencl_kernels_core.hpp" #include @@ -2420,7 +2420,7 @@ namespace cv { #define CLAMDDFT_Assert(func) \ { \ - clAmdFftStatus s = (func); \ + clfftStatus s = (func); \ CV_Assert(s == CLFFT_SUCCESS); \ } @@ -2437,8 +2437,8 @@ class PlanCache bool dft_scale = (flags & DFT_SCALE) != 0; bool dft_rows = (flags & DFT_ROWS) != 0; - clAmdFftLayout inLayout = CLFFT_REAL, outLayout = CLFFT_REAL; - clAmdFftDim dim = dft_size.height == 1 || dft_rows ? CLFFT_1D : CLFFT_2D; + clfftLayout inLayout = CLFFT_REAL, outLayout = CLFFT_REAL; + clfftDim dim = dft_size.height == 1 || dft_rows ? CLFFT_1D : CLFFT_2D; size_t batchSize = dft_rows ? dft_size.height : 1; size_t clLengthsIn[3] = { (size_t)dft_size.width, dft_rows ? 1 : (size_t)dft_size.height, 1 }; @@ -2475,28 +2475,30 @@ class PlanCache clStridesIn[2] = dft_rows ? clStridesIn[1] : dft_size.width * clStridesIn[1]; clStridesOut[2] = dft_rows ? clStridesOut[1] : dft_size.width * clStridesOut[1]; - CLAMDDFT_Assert(clAmdFftCreateDefaultPlan(&plHandle, (cl_context)ocl::Context::getDefault().ptr(), dim, clLengthsIn)) + CLAMDDFT_Assert(clfftCreateDefaultPlan(&plHandle, (cl_context)ocl::Context::getDefault().ptr(), dim, clLengthsIn)) // setting plan properties - CLAMDDFT_Assert(clAmdFftSetPlanPrecision(plHandle, doubleFP ? CLFFT_DOUBLE : CLFFT_SINGLE)); - CLAMDDFT_Assert(clAmdFftSetResultLocation(plHandle, inplace ? CLFFT_INPLACE : CLFFT_OUTOFPLACE)) - CLAMDDFT_Assert(clAmdFftSetLayout(plHandle, inLayout, outLayout)) - CLAMDDFT_Assert(clAmdFftSetPlanBatchSize(plHandle, batchSize)) - CLAMDDFT_Assert(clAmdFftSetPlanInStride(plHandle, dim, clStridesIn)) - CLAMDDFT_Assert(clAmdFftSetPlanOutStride(plHandle, dim, clStridesOut)) - CLAMDDFT_Assert(clAmdFftSetPlanDistance(plHandle, clStridesIn[dim], clStridesOut[dim])) + CLAMDDFT_Assert(clfftSetPlanPrecision(plHandle, doubleFP ? CLFFT_DOUBLE : CLFFT_SINGLE)); + CLAMDDFT_Assert(clfftSetResultLocation(plHandle, inplace ? CLFFT_INPLACE : CLFFT_OUTOFPLACE)) + CLAMDDFT_Assert(clfftSetLayout(plHandle, inLayout, outLayout)) + CLAMDDFT_Assert(clfftSetPlanBatchSize(plHandle, batchSize)) + CLAMDDFT_Assert(clfftSetPlanInStride(plHandle, dim, clStridesIn)) + CLAMDDFT_Assert(clfftSetPlanOutStride(plHandle, dim, clStridesOut)) + CLAMDDFT_Assert(clfftSetPlanDistance(plHandle, clStridesIn[dim], clStridesOut[dim])) float scale = dft_scale ? 1.0f / (dft_rows ? dft_size.width : dft_size.area()) : 1.0f; - CLAMDDFT_Assert(clAmdFftSetPlanScale(plHandle, dft_inverse ? CLFFT_BACKWARD : CLFFT_FORWARD, scale)) + CLAMDDFT_Assert(clfftSetPlanScale(plHandle, dft_inverse ? CLFFT_BACKWARD : CLFFT_FORWARD, scale)) // ready to bake cl_command_queue queue = (cl_command_queue)ocl::Queue::getDefault().ptr(); - CLAMDDFT_Assert(clAmdFftBakePlan(plHandle, 1, &queue, NULL, NULL)) + CLAMDDFT_Assert(clfftBakePlan(plHandle, 1, &queue, NULL, NULL)) } ~FftPlan() { -// clAmdFftDestroyPlan(&plHandle); + // Do not tear down clFFT. + // The user application may still use clFFT even after OpenCV is unloaded. + /*clfftDestroyPlan(&plHandle);*/ } friend class PlanCache; @@ -2510,7 +2512,7 @@ class PlanCache FftType fftType; cl_context context; - clAmdFftPlanHandle plHandle; + clfftPlanHandle plHandle; }; public: @@ -2519,8 +2521,8 @@ class PlanCache CV_SINGLETON_LAZY_INIT_REF(PlanCache, new PlanCache()) } - clAmdFftPlanHandle getPlanHandle(const Size & dft_size, int src_step, int dst_step, bool doubleFP, - bool inplace, int flags, FftType fftType) + clfftPlanHandle getPlanHandle(const Size & dft_size, int src_step, int dst_step, bool doubleFP, + bool inplace, int flags, FftType fftType) { cl_context currentContext = (cl_context)ocl::Context::getDefault().ptr(); @@ -2620,13 +2622,13 @@ static bool ocl_dft_amdfft(InputArray _src, OutputArray _dst, int flags) UMat src = _src.getUMat(), dst = _dst.getUMat(); bool inplace = src.u == dst.u; - clAmdFftPlanHandle plHandle = PlanCache::getInstance(). + clfftPlanHandle plHandle = PlanCache::getInstance(). getPlanHandle(ssize, (int)src.step, (int)dst.step, depth == CV_64F, inplace, flags, fftType); // get the bufferSize size_t bufferSize = 0; - CLAMDDFT_Assert(clAmdFftGetTmpBufSize(plHandle, &bufferSize)) + CLAMDDFT_Assert(clfftGetTmpBufSize(plHandle, &bufferSize)) UMat tmpBuffer(1, (int)bufferSize, CV_8UC1); cl_mem srcarg = (cl_mem)src.handle(ACCESS_READ); @@ -2635,9 +2637,9 @@ static bool ocl_dft_amdfft(InputArray _src, OutputArray _dst, int flags) cl_command_queue queue = (cl_command_queue)ocl::Queue::getDefault().ptr(); cl_event e = 0; - CLAMDDFT_Assert(clAmdFftEnqueueTransform(plHandle, dft_inverse ? CLFFT_BACKWARD : CLFFT_FORWARD, - 1, &queue, 0, NULL, &e, - &srcarg, &dstarg, (cl_mem)tmpBuffer.handle(ACCESS_RW))) + CLAMDDFT_Assert(clfftEnqueueTransform(plHandle, dft_inverse ? CLFFT_BACKWARD : CLFFT_FORWARD, + 1, &queue, 0, NULL, &e, + &srcarg, &dstarg, (cl_mem)tmpBuffer.handle(ACCESS_RW))) tmpBuffer.addref(); clSetEventCallback(e, CL_COMPLETE, oclCleanupCallback, tmpBuffer.u); diff --git a/modules/core/src/intel_gpu_gemm.inl.hpp b/modules/core/src/intel_gpu_gemm.inl.hpp index fbd567b949e3..a73e71a67da7 100644 --- a/modules/core/src/intel_gpu_gemm.inl.hpp +++ b/modules/core/src/intel_gpu_gemm.inl.hpp @@ -26,7 +26,7 @@ #include #include "opencl_kernels_core.hpp" -#include "opencv2/core/opencl/runtime/opencl_clamdblas.hpp" +#include "opencv2/core/opencl/runtime/opencl_clblas.hpp" #include "opencv2/core/opencl/runtime/opencl_core.hpp" namespace cv diff --git a/modules/core/src/matmul.dispatch.cpp b/modules/core/src/matmul.dispatch.cpp index f4bd14b5ddd7..651c4544906b 100644 --- a/modules/core/src/matmul.dispatch.cpp +++ b/modules/core/src/matmul.dispatch.cpp @@ -43,7 +43,7 @@ #include "precomp.hpp" #include "opencl_kernels_core.hpp" -#include "opencv2/core/opencl/runtime/opencl_clamdblas.hpp" +#include "opencv2/core/opencl/runtime/opencl_clblas.hpp" #include "opencv2/core/opencl/runtime/opencl_core.hpp" #include "intel_gpu_gemm.inl.hpp" @@ -106,47 +106,47 @@ static bool ocl_gemm_amdblas( InputArray matA, InputArray matB, double alpha, int offa = (int)A.offset / esz, offb = (int)B.offset / esz, offc = (int)D.offset / esz; cl_command_queue clq = (cl_command_queue)ocl::Queue::getDefault().ptr(); - clAmdBlasTranspose transA = atrans ? clAmdBlasTrans : clAmdBlasNoTrans; - clAmdBlasTranspose transB = btrans ? clAmdBlasTrans : clAmdBlasNoTrans; - clAmdBlasOrder order = clAmdBlasRowMajor; - clAmdBlasStatus status = clAmdBlasSuccess; + clblasTranspose transA = atrans ? clblasTrans : clblasNoTrans; + clblasTranspose transB = btrans ? clblasTrans : clblasNoTrans; + clblasOrder order = clblasRowMajor; + clblasStatus status = clblasSuccess; if (type == CV_32FC1) - status = clAmdBlasSgemmEx(order, transA, transB, M, N, K, - (cl_float)alpha, (const cl_mem)A.handle(ACCESS_READ), offa, lda, - (const cl_mem)B.handle(ACCESS_READ), offb, ldb, - (cl_float)beta, (cl_mem)D.handle(ACCESS_RW), offc, ldc, - 1, &clq, 0, NULL, NULL); + status = clblasSgemm(order, transA, transB, M, N, K, + (cl_float)alpha, (const cl_mem)A.handle(ACCESS_READ), offa, lda, + (const cl_mem)B.handle(ACCESS_READ), offb, ldb, + (cl_float)beta, (cl_mem)D.handle(ACCESS_RW), offc, ldc, + 1, &clq, 0, NULL, NULL); else if (type == CV_64FC1) - status = clAmdBlasDgemmEx(order, transA, transB, M, N, K, - alpha, (const cl_mem)A.handle(ACCESS_READ), offa, lda, - (const cl_mem)B.handle(ACCESS_READ), offb, ldb, - beta, (cl_mem)D.handle(ACCESS_RW), offc, ldc, - 1, &clq, 0, NULL, NULL); + status = clblasDgemm(order, transA, transB, M, N, K, + alpha, (const cl_mem)A.handle(ACCESS_READ), offa, lda, + (const cl_mem)B.handle(ACCESS_READ), offb, ldb, + beta, (cl_mem)D.handle(ACCESS_RW), offc, ldc, + 1, &clq, 0, NULL, NULL); else if (type == CV_32FC2) { cl_float2 alpha_2 = { { (cl_float)alpha, 0 } }; cl_float2 beta_2 = { { (cl_float)beta, 0 } }; - status = clAmdBlasCgemmEx(order, transA, transB, M, N, K, - alpha_2, (const cl_mem)A.handle(ACCESS_READ), offa, lda, - (const cl_mem)B.handle(ACCESS_READ), offb, ldb, - beta_2, (cl_mem)D.handle(ACCESS_RW), offc, ldc, - 1, &clq, 0, NULL, NULL); + status = clblasCgemm(order, transA, transB, M, N, K, + alpha_2, (const cl_mem)A.handle(ACCESS_READ), offa, lda, + (const cl_mem)B.handle(ACCESS_READ), offb, ldb, + beta_2, (cl_mem)D.handle(ACCESS_RW), offc, ldc, + 1, &clq, 0, NULL, NULL); } else if (type == CV_64FC2) { cl_double2 alpha_2 = { { alpha, 0 } }; cl_double2 beta_2 = { { beta, 0 } }; - status = clAmdBlasZgemmEx(order, transA, transB, M, N, K, - alpha_2, (const cl_mem)A.handle(ACCESS_READ), offa, lda, - (const cl_mem)B.handle(ACCESS_READ), offb, ldb, - beta_2, (cl_mem)D.handle(ACCESS_RW), offc, ldc, - 1, &clq, 0, NULL, NULL); + status = clblasZgemm(order, transA, transB, M, N, K, + alpha_2, (const cl_mem)A.handle(ACCESS_READ), offa, lda, + (const cl_mem)B.handle(ACCESS_READ), offb, ldb, + beta_2, (cl_mem)D.handle(ACCESS_RW), offc, ldc, + 1, &clq, 0, NULL, NULL); } else CV_Error(Error::StsUnsupportedFormat, ""); - return status == clAmdBlasSuccess; + return status == clblasSuccess; } #endif diff --git a/modules/core/src/matrix_operations.cpp b/modules/core/src/matrix_operations.cpp index 83c8aaeb5705..227c7aaef774 100644 --- a/modules/core/src/matrix_operations.cpp +++ b/modules/core/src/matrix_operations.cpp @@ -229,14 +229,14 @@ void cv::setIdentity( InputOutputArray _m, const Scalar& s ) namespace cv { -UMat UMat::eye(int rows, int cols, int type) +UMat UMat::eye(int rows, int cols, int type, UMatUsageFlags usageFlags) { - return UMat::eye(Size(cols, rows), type); + return UMat::eye(Size(cols, rows), type, usageFlags); } -UMat UMat::eye(Size size, int type) +UMat UMat::eye(Size size, int type, UMatUsageFlags usageFlags) { - UMat m(size, type); + UMat m(size, type, usageFlags); setIdentity(m); return m; } diff --git a/modules/core/src/norm.cpp b/modules/core/src/norm.cpp index bbefefc95d2f..4df25f495722 100644 --- a/modules/core/src/norm.cpp +++ b/modules/core/src/norm.cpp @@ -1194,7 +1194,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask // special case to handle "integer" overflow in accumulator const size_t esz = src1.elemSize(); const int total = (int)it.size; - const int intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15); + const int intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn; const int blockSize = std::min(total, intSumBlockSize); int isum = 0; int count = 0; diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 046863912927..46185446f726 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -108,8 +108,8 @@ #define CV_OPENCL_SVM_TRACE_ERROR_P(...) #endif -#include "opencv2/core/opencl/runtime/opencl_clamdblas.hpp" -#include "opencv2/core/opencl/runtime/opencl_clamdfft.hpp" +#include "opencv2/core/opencl/runtime/opencl_clblas.hpp" +#include "opencv2/core/opencl/runtime/opencl_clfft.hpp" #include "opencv2/core/opencl/runtime/opencl_core.hpp" @@ -1254,11 +1254,13 @@ class AmdBlasHelper ~AmdBlasHelper() { - try + // Do not tear down clBLAS. + // The user application may still use clBLAS even after OpenCV is unloaded. + /*try { - clAmdBlasTeardown(); + clblasTeardown(); } - catch (...) { } + catch (...) { }*/ } protected: @@ -1274,7 +1276,7 @@ class AmdBlasHelper { try { - g_isAmdBlasAvailable = clAmdBlasSetup() == clAmdBlasSuccess; + g_isAmdBlasAvailable = clblasSetup() == clblasSuccess; } catch (...) { @@ -1328,11 +1330,13 @@ class AmdFftHelper ~AmdFftHelper() { - try + // Do not tear down clFFT. + // The user application may still use clFFT even after OpenCV is unloaded. + /*try { -// clAmdFftTeardown(); + clfftTeardown(); } - catch (...) { } + catch (...) { }*/ } protected: @@ -1349,10 +1353,10 @@ class AmdFftHelper try { cl_uint major, minor, patch; - CV_Assert(clAmdFftInitSetupData(&setupData) == CLFFT_SUCCESS); + CV_Assert(clfftInitSetupData(&setupData) == CLFFT_SUCCESS); // it throws exception in case AmdFft binaries are not found - CV_Assert(clAmdFftGetVersion(&major, &minor, &patch) == CLFFT_SUCCESS); + CV_Assert(clfftGetVersion(&major, &minor, &patch) == CLFFT_SUCCESS); g_isAmdFftAvailable = true; } catch (const Exception &) @@ -1369,12 +1373,12 @@ class AmdFftHelper } private: - static clAmdFftSetupData setupData; + static clfftSetupData setupData; static bool g_isAmdFftInitialized; static bool g_isAmdFftAvailable; }; -clAmdFftSetupData AmdFftHelper::setupData; +clfftSetupData AmdFftHelper::setupData; bool AmdFftHelper::g_isAmdFftAvailable = false; bool AmdFftHelper::g_isAmdFftInitialized = false; @@ -1562,6 +1566,7 @@ struct Device::Impl version_ = getStrProp(CL_DEVICE_VERSION); extensions_ = getStrProp(CL_DEVICE_EXTENSIONS); doubleFPConfig_ = getProp(CL_DEVICE_DOUBLE_FP_CONFIG); + halfFPConfig_ = getProp(CL_DEVICE_HALF_FP_CONFIG); hostUnifiedMemory_ = getBoolProp(CL_DEVICE_HOST_UNIFIED_MEMORY); maxComputeUnits_ = getProp(CL_DEVICE_MAX_COMPUTE_UNITS); maxWorkGroupSize_ = getProp(CL_DEVICE_MAX_WORK_GROUP_SIZE); @@ -1674,6 +1679,7 @@ struct Device::Impl String version_; std::string extensions_; int doubleFPConfig_; + int halfFPConfig_; bool hostUnifiedMemory_; int maxComputeUnits_; size_t maxWorkGroupSize_; @@ -1823,11 +1829,7 @@ int Device::singleFPConfig() const { return p ? p->getProp(CL_DEVICE_SINGLE_FP_CONFIG) : 0; } int Device::halfFPConfig() const -#ifdef CL_VERSION_1_2 -{ return p ? p->getProp(CL_DEVICE_HALF_FP_CONFIG) : 0; } -#else -{ CV_REQUIRE_OPENCL_1_2_ERROR; } -#endif +{ return p ? p->halfFPConfig_ : 0; } bool Device::endianLittle() const { return p ? p->getBoolProp(CL_DEVICE_ENDIAN_LITTLE) : false; } @@ -3482,7 +3484,6 @@ struct Kernel::Impl void registerImageArgument(int arg, const Image2D& image) { CV_CheckGE(arg, 0, ""); - CV_CheckLT(arg, (int)MAX_ARRS, ""); if (arg < (int)shadow_images.size() && shadow_images[arg].ptr() != image.ptr()) // TODO future: replace ptr => impl (more strong check) { CV_Check(arg, !isInProgress, "ocl::Kernel: clearing of pending Image2D arguments is not allowed"); @@ -5519,13 +5520,19 @@ class OpenCLAllocator CV_FINAL : public MatAllocator && !(u->originalUMatData && u->originalUMatData->handle) ) { - handle = clCreateBuffer(ctx_handle, CL_MEM_USE_HOST_PTR|createFlags, + // Change the host-side origdata[size] to "pinned memory" that enables fast + // DMA-transfers over PCIe to the device. Often used with clEnqueueMapBuffer/clEnqueueUnmapMemObject + handle = clCreateBuffer(ctx_handle, CL_MEM_USE_HOST_PTR|(createFlags & ~CL_MEM_ALLOC_HOST_PTR), u->size, u->origdata, &retval); - CV_OCL_DBG_CHECK_RESULT(retval, cv::format("clCreateBuffer(CL_MEM_USE_HOST_PTR|createFlags, sz=%lld, origdata=%p) => %p", + CV_OCL_DBG_CHECK_RESULT(retval, cv::format("clCreateBuffer(CL_MEM_USE_HOST_PTR|(createFlags & ~CL_MEM_ALLOC_HOST_PTR), sz=%lld, origdata=%p) => %p", (long long int)u->size, u->origdata, (void*)handle).c_str()); } if((!handle || retval < 0) && !(accessFlags & ACCESS_FAST)) { + // Allocate device-side memory and immediately copy data from the host-side pointer origdata[size]. + // If createFlags=CL_MEM_ALLOC_HOST_PTR (aka cv::USAGE_ALLOCATE_HOST_MEMORY), then + // additionally allocate a host-side "pinned" duplicate of the origdata that is + // managed by OpenCL. This is potentially faster in unaligned/unmanaged scenarios. handle = clCreateBuffer(ctx_handle, CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE|createFlags, u->size, u->origdata, &retval); CV_OCL_DBG_CHECK_RESULT(retval, cv::format("clCreateBuffer(CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE|createFlags, sz=%lld, origdata=%p) => %p", @@ -6659,6 +6666,10 @@ void convertFromImage(void* cl_mem_image, UMat& dst) depth = CV_32F; break; + case CL_HALF_FLOAT: + depth = CV_16F; + break; + default: CV_Error(cv::Error::OpenCLApiCallError, "Not supported image_channel_data_type"); } @@ -6667,9 +6678,23 @@ void convertFromImage(void* cl_mem_image, UMat& dst) switch (fmt.image_channel_order) { case CL_R: + case CL_A: + case CL_INTENSITY: + case CL_LUMINANCE: type = CV_MAKE_TYPE(depth, 1); break; + case CL_RG: + case CL_RA: + type = CV_MAKE_TYPE(depth, 2); + break; + + // CL_RGB has no mappings to OpenCV types because CL_RGB can only be used with + // CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, or CL_UNORM_INT_101010. + /*case CL_RGB: + type = CV_MAKE_TYPE(depth, 3); + break;*/ + case CL_RGBA: case CL_BGRA: case CL_ARGB: @@ -7059,6 +7084,13 @@ static std::string kerToStr(const Mat & k) stream << "DIG(" << data[i] << "f)"; stream << "DIG(" << data[width] << "f)"; } + else if (depth == CV_16F) + { + stream.setf(std::ios_base::showpoint); + for (int i = 0; i < width; ++i) + stream << "DIG(" << (float)data[i] << "h)"; + stream << "DIG(" << (float)data[width] << "h)"; + } else { for (int i = 0; i < width; ++i) @@ -7082,7 +7114,7 @@ String kernelToStr(InputArray _kernel, int ddepth, const char * name) typedef std::string (* func_t)(const Mat &); static const func_t funcs[] = { kerToStr, kerToStr, kerToStr, kerToStr, - kerToStr, kerToStr, kerToStr, 0 }; + kerToStr, kerToStr, kerToStr, kerToStr }; const func_t func = funcs[ddepth]; CV_Assert(func != 0); @@ -7121,14 +7153,14 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3, int vectorWidths[] = { d.preferredVectorWidthChar(), d.preferredVectorWidthChar(), d.preferredVectorWidthShort(), d.preferredVectorWidthShort(), d.preferredVectorWidthInt(), d.preferredVectorWidthFloat(), - d.preferredVectorWidthDouble(), -1 }; + d.preferredVectorWidthDouble(), d.preferredVectorWidthHalf() }; // if the device says don't use vectors if (vectorWidths[0] == 1) { // it's heuristic vectorWidths[CV_8U] = vectorWidths[CV_8S] = 4; - vectorWidths[CV_16U] = vectorWidths[CV_16S] = 2; + vectorWidths[CV_16U] = vectorWidths[CV_16S] = vectorWidths[CV_16F] = 2; vectorWidths[CV_32S] = vectorWidths[CV_32F] = vectorWidths[CV_64F] = 1; } @@ -7216,10 +7248,12 @@ struct Image2D::Impl { cl_image_format format; static const int channelTypes[] = { CL_UNSIGNED_INT8, CL_SIGNED_INT8, CL_UNSIGNED_INT16, - CL_SIGNED_INT16, CL_SIGNED_INT32, CL_FLOAT, -1, -1 }; + CL_SIGNED_INT16, CL_SIGNED_INT32, CL_FLOAT, -1, CL_HALF_FLOAT }; static const int channelTypesNorm[] = { CL_UNORM_INT8, CL_SNORM_INT8, CL_UNORM_INT16, CL_SNORM_INT16, -1, -1, -1, -1 }; - static const int channelOrders[] = { -1, CL_R, CL_RG, -1, CL_RGBA }; + // CL_RGB has no mappings to OpenCV types because CL_RGB can only be used with + // CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, or CL_UNORM_INT_101010. + static const int channelOrders[] = { -1, CL_R, CL_RG, /*CL_RGB*/ -1, CL_RGBA }; int channelType = norm ? channelTypesNorm[depth] : channelTypes[depth]; int channelOrder = channelOrders[cn]; diff --git a/modules/core/src/opencl/runtime/autogenerated/opencl_clamdblas_impl.hpp b/modules/core/src/opencl/runtime/autogenerated/opencl_clamdblas_impl.hpp deleted file mode 100644 index 9c7e4d1480ef..000000000000 --- a/modules/core/src/opencl/runtime/autogenerated/opencl_clamdblas_impl.hpp +++ /dev/null @@ -1,1358 +0,0 @@ -// -// AUTOGENERATED, DO NOT EDIT -// -// generated by parser_clamdblas.py -enum OPENCLAMDBLAS_FN_ID { -// OPENCLAMDBLAS_FN_clAmdBlasAddScratchImage = 0, -// OPENCLAMDBLAS_FN_clAmdBlasCaxpy = 1, -// OPENCLAMDBLAS_FN_clAmdBlasCcopy = 2, -// OPENCLAMDBLAS_FN_clAmdBlasCdotc = 3, -// OPENCLAMDBLAS_FN_clAmdBlasCdotu = 4, -// OPENCLAMDBLAS_FN_clAmdBlasCgbmv = 5, -// OPENCLAMDBLAS_FN_clAmdBlasCgemm = 6, - OPENCLAMDBLAS_FN_clAmdBlasCgemmEx = 7, -// OPENCLAMDBLAS_FN_clAmdBlasCgemv = 8, -// OPENCLAMDBLAS_FN_clAmdBlasCgemvEx = 9, -// OPENCLAMDBLAS_FN_clAmdBlasCgerc = 10, -// OPENCLAMDBLAS_FN_clAmdBlasCgeru = 11, -// OPENCLAMDBLAS_FN_clAmdBlasChbmv = 12, -// OPENCLAMDBLAS_FN_clAmdBlasChemm = 13, -// OPENCLAMDBLAS_FN_clAmdBlasChemv = 14, -// OPENCLAMDBLAS_FN_clAmdBlasCher = 15, -// OPENCLAMDBLAS_FN_clAmdBlasCher2 = 16, -// OPENCLAMDBLAS_FN_clAmdBlasCher2k = 17, -// OPENCLAMDBLAS_FN_clAmdBlasCherk = 18, -// OPENCLAMDBLAS_FN_clAmdBlasChpmv = 19, -// OPENCLAMDBLAS_FN_clAmdBlasChpr = 20, -// OPENCLAMDBLAS_FN_clAmdBlasChpr2 = 21, -// OPENCLAMDBLAS_FN_clAmdBlasCrotg = 22, -// OPENCLAMDBLAS_FN_clAmdBlasCscal = 23, -// OPENCLAMDBLAS_FN_clAmdBlasCsrot = 24, -// OPENCLAMDBLAS_FN_clAmdBlasCsscal = 25, -// OPENCLAMDBLAS_FN_clAmdBlasCswap = 26, -// OPENCLAMDBLAS_FN_clAmdBlasCsymm = 27, -// OPENCLAMDBLAS_FN_clAmdBlasCsyr2k = 28, -// OPENCLAMDBLAS_FN_clAmdBlasCsyr2kEx = 29, -// OPENCLAMDBLAS_FN_clAmdBlasCsyrk = 30, -// OPENCLAMDBLAS_FN_clAmdBlasCsyrkEx = 31, -// OPENCLAMDBLAS_FN_clAmdBlasCtbmv = 32, -// OPENCLAMDBLAS_FN_clAmdBlasCtbsv = 33, -// OPENCLAMDBLAS_FN_clAmdBlasCtpmv = 34, -// OPENCLAMDBLAS_FN_clAmdBlasCtpsv = 35, -// OPENCLAMDBLAS_FN_clAmdBlasCtrmm = 36, -// OPENCLAMDBLAS_FN_clAmdBlasCtrmmEx = 37, -// OPENCLAMDBLAS_FN_clAmdBlasCtrmv = 38, -// OPENCLAMDBLAS_FN_clAmdBlasCtrsm = 39, -// OPENCLAMDBLAS_FN_clAmdBlasCtrsmEx = 40, -// OPENCLAMDBLAS_FN_clAmdBlasCtrsv = 41, -// OPENCLAMDBLAS_FN_clAmdBlasDasum = 42, -// OPENCLAMDBLAS_FN_clAmdBlasDaxpy = 43, -// OPENCLAMDBLAS_FN_clAmdBlasDcopy = 44, -// OPENCLAMDBLAS_FN_clAmdBlasDdot = 45, -// OPENCLAMDBLAS_FN_clAmdBlasDgbmv = 46, -// OPENCLAMDBLAS_FN_clAmdBlasDgemm = 47, - OPENCLAMDBLAS_FN_clAmdBlasDgemmEx = 48, -// OPENCLAMDBLAS_FN_clAmdBlasDgemv = 49, -// OPENCLAMDBLAS_FN_clAmdBlasDgemvEx = 50, -// OPENCLAMDBLAS_FN_clAmdBlasDger = 51, -// OPENCLAMDBLAS_FN_clAmdBlasDnrm2 = 52, -// OPENCLAMDBLAS_FN_clAmdBlasDrot = 53, -// OPENCLAMDBLAS_FN_clAmdBlasDrotg = 54, -// OPENCLAMDBLAS_FN_clAmdBlasDrotm = 55, -// OPENCLAMDBLAS_FN_clAmdBlasDrotmg = 56, -// OPENCLAMDBLAS_FN_clAmdBlasDsbmv = 57, -// OPENCLAMDBLAS_FN_clAmdBlasDscal = 58, -// OPENCLAMDBLAS_FN_clAmdBlasDspmv = 59, -// OPENCLAMDBLAS_FN_clAmdBlasDspr = 60, -// OPENCLAMDBLAS_FN_clAmdBlasDspr2 = 61, -// OPENCLAMDBLAS_FN_clAmdBlasDswap = 62, -// OPENCLAMDBLAS_FN_clAmdBlasDsymm = 63, -// OPENCLAMDBLAS_FN_clAmdBlasDsymv = 64, -// OPENCLAMDBLAS_FN_clAmdBlasDsymvEx = 65, -// OPENCLAMDBLAS_FN_clAmdBlasDsyr = 66, -// OPENCLAMDBLAS_FN_clAmdBlasDsyr2 = 67, -// OPENCLAMDBLAS_FN_clAmdBlasDsyr2k = 68, -// OPENCLAMDBLAS_FN_clAmdBlasDsyr2kEx = 69, -// OPENCLAMDBLAS_FN_clAmdBlasDsyrk = 70, -// OPENCLAMDBLAS_FN_clAmdBlasDsyrkEx = 71, -// OPENCLAMDBLAS_FN_clAmdBlasDtbmv = 72, -// OPENCLAMDBLAS_FN_clAmdBlasDtbsv = 73, -// OPENCLAMDBLAS_FN_clAmdBlasDtpmv = 74, -// OPENCLAMDBLAS_FN_clAmdBlasDtpsv = 75, -// OPENCLAMDBLAS_FN_clAmdBlasDtrmm = 76, -// OPENCLAMDBLAS_FN_clAmdBlasDtrmmEx = 77, -// OPENCLAMDBLAS_FN_clAmdBlasDtrmv = 78, -// OPENCLAMDBLAS_FN_clAmdBlasDtrsm = 79, -// OPENCLAMDBLAS_FN_clAmdBlasDtrsmEx = 80, -// OPENCLAMDBLAS_FN_clAmdBlasDtrsv = 81, -// OPENCLAMDBLAS_FN_clAmdBlasDzasum = 82, -// OPENCLAMDBLAS_FN_clAmdBlasDznrm2 = 83, -// OPENCLAMDBLAS_FN_clAmdBlasGetVersion = 84, -// OPENCLAMDBLAS_FN_clAmdBlasRemoveScratchImage = 85, -// OPENCLAMDBLAS_FN_clAmdBlasSasum = 86, -// OPENCLAMDBLAS_FN_clAmdBlasSaxpy = 87, -// OPENCLAMDBLAS_FN_clAmdBlasScasum = 88, -// OPENCLAMDBLAS_FN_clAmdBlasScnrm2 = 89, -// OPENCLAMDBLAS_FN_clAmdBlasScopy = 90, -// OPENCLAMDBLAS_FN_clAmdBlasSdot = 91, - OPENCLAMDBLAS_FN_clAmdBlasSetup = 92, -// OPENCLAMDBLAS_FN_clAmdBlasSgbmv = 93, -// OPENCLAMDBLAS_FN_clAmdBlasSgemm = 94, - OPENCLAMDBLAS_FN_clAmdBlasSgemmEx = 95, -// OPENCLAMDBLAS_FN_clAmdBlasSgemv = 96, -// OPENCLAMDBLAS_FN_clAmdBlasSgemvEx = 97, -// OPENCLAMDBLAS_FN_clAmdBlasSger = 98, -// OPENCLAMDBLAS_FN_clAmdBlasSnrm2 = 99, -// OPENCLAMDBLAS_FN_clAmdBlasSrot = 100, -// OPENCLAMDBLAS_FN_clAmdBlasSrotg = 101, -// OPENCLAMDBLAS_FN_clAmdBlasSrotm = 102, -// OPENCLAMDBLAS_FN_clAmdBlasSrotmg = 103, -// OPENCLAMDBLAS_FN_clAmdBlasSsbmv = 104, -// OPENCLAMDBLAS_FN_clAmdBlasSscal = 105, -// OPENCLAMDBLAS_FN_clAmdBlasSspmv = 106, -// OPENCLAMDBLAS_FN_clAmdBlasSspr = 107, -// OPENCLAMDBLAS_FN_clAmdBlasSspr2 = 108, -// OPENCLAMDBLAS_FN_clAmdBlasSswap = 109, -// OPENCLAMDBLAS_FN_clAmdBlasSsymm = 110, -// OPENCLAMDBLAS_FN_clAmdBlasSsymv = 111, -// OPENCLAMDBLAS_FN_clAmdBlasSsymvEx = 112, -// OPENCLAMDBLAS_FN_clAmdBlasSsyr = 113, -// OPENCLAMDBLAS_FN_clAmdBlasSsyr2 = 114, -// OPENCLAMDBLAS_FN_clAmdBlasSsyr2k = 115, -// OPENCLAMDBLAS_FN_clAmdBlasSsyr2kEx = 116, -// OPENCLAMDBLAS_FN_clAmdBlasSsyrk = 117, -// OPENCLAMDBLAS_FN_clAmdBlasSsyrkEx = 118, -// OPENCLAMDBLAS_FN_clAmdBlasStbmv = 119, -// OPENCLAMDBLAS_FN_clAmdBlasStbsv = 120, -// OPENCLAMDBLAS_FN_clAmdBlasStpmv = 121, -// OPENCLAMDBLAS_FN_clAmdBlasStpsv = 122, -// OPENCLAMDBLAS_FN_clAmdBlasStrmm = 123, -// OPENCLAMDBLAS_FN_clAmdBlasStrmmEx = 124, -// OPENCLAMDBLAS_FN_clAmdBlasStrmv = 125, -// OPENCLAMDBLAS_FN_clAmdBlasStrsm = 126, -// OPENCLAMDBLAS_FN_clAmdBlasStrsmEx = 127, -// OPENCLAMDBLAS_FN_clAmdBlasStrsv = 128, - OPENCLAMDBLAS_FN_clAmdBlasTeardown = 129, -// OPENCLAMDBLAS_FN_clAmdBlasZaxpy = 130, -// OPENCLAMDBLAS_FN_clAmdBlasZcopy = 131, -// OPENCLAMDBLAS_FN_clAmdBlasZdotc = 132, -// OPENCLAMDBLAS_FN_clAmdBlasZdotu = 133, -// OPENCLAMDBLAS_FN_clAmdBlasZdrot = 134, -// OPENCLAMDBLAS_FN_clAmdBlasZdscal = 135, -// OPENCLAMDBLAS_FN_clAmdBlasZgbmv = 136, -// OPENCLAMDBLAS_FN_clAmdBlasZgemm = 137, - OPENCLAMDBLAS_FN_clAmdBlasZgemmEx = 138, -// OPENCLAMDBLAS_FN_clAmdBlasZgemv = 139, -// OPENCLAMDBLAS_FN_clAmdBlasZgemvEx = 140, -// OPENCLAMDBLAS_FN_clAmdBlasZgerc = 141, -// OPENCLAMDBLAS_FN_clAmdBlasZgeru = 142, -// OPENCLAMDBLAS_FN_clAmdBlasZhbmv = 143, -// OPENCLAMDBLAS_FN_clAmdBlasZhemm = 144, -// OPENCLAMDBLAS_FN_clAmdBlasZhemv = 145, -// OPENCLAMDBLAS_FN_clAmdBlasZher = 146, -// OPENCLAMDBLAS_FN_clAmdBlasZher2 = 147, -// OPENCLAMDBLAS_FN_clAmdBlasZher2k = 148, -// OPENCLAMDBLAS_FN_clAmdBlasZherk = 149, -// OPENCLAMDBLAS_FN_clAmdBlasZhpmv = 150, -// OPENCLAMDBLAS_FN_clAmdBlasZhpr = 151, -// OPENCLAMDBLAS_FN_clAmdBlasZhpr2 = 152, -// OPENCLAMDBLAS_FN_clAmdBlasZrotg = 153, -// OPENCLAMDBLAS_FN_clAmdBlasZscal = 154, -// OPENCLAMDBLAS_FN_clAmdBlasZswap = 155, -// OPENCLAMDBLAS_FN_clAmdBlasZsymm = 156, -// OPENCLAMDBLAS_FN_clAmdBlasZsyr2k = 157, -// OPENCLAMDBLAS_FN_clAmdBlasZsyr2kEx = 158, -// OPENCLAMDBLAS_FN_clAmdBlasZsyrk = 159, -// OPENCLAMDBLAS_FN_clAmdBlasZsyrkEx = 160, -// OPENCLAMDBLAS_FN_clAmdBlasZtbmv = 161, -// OPENCLAMDBLAS_FN_clAmdBlasZtbsv = 162, -// OPENCLAMDBLAS_FN_clAmdBlasZtpmv = 163, -// OPENCLAMDBLAS_FN_clAmdBlasZtpsv = 164, -// OPENCLAMDBLAS_FN_clAmdBlasZtrmm = 165, -// OPENCLAMDBLAS_FN_clAmdBlasZtrmmEx = 166, -// OPENCLAMDBLAS_FN_clAmdBlasZtrmv = 167, -// OPENCLAMDBLAS_FN_clAmdBlasZtrsm = 168, -// OPENCLAMDBLAS_FN_clAmdBlasZtrsmEx = 169, -// OPENCLAMDBLAS_FN_clAmdBlasZtrsv = 170, -// OPENCLAMDBLAS_FN_clAmdBlasiCamax = 171, -// OPENCLAMDBLAS_FN_clAmdBlasiDamax = 172, -// OPENCLAMDBLAS_FN_clAmdBlasiSamax = 173, -// OPENCLAMDBLAS_FN_clAmdBlasiZamax = 174, -}; - -namespace { -// generated by parser_clamdblas.py -#define openclamdblas_fn0(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(); } \ - -#define openclamdblas_fn1(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1); } \ - -#define openclamdblas_fn2(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2); } \ - -#define openclamdblas_fn3(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3); } \ - -#define openclamdblas_fn4(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4); } \ - -#define openclamdblas_fn5(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5); } \ - -#define openclamdblas_fn6(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6); } \ - -#define openclamdblas_fn7(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7); } \ - -#define openclamdblas_fn8(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8); } \ - -#define openclamdblas_fn9(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } \ - -#define openclamdblas_fn10(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } \ - -#define openclamdblas_fn11(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } \ - -#define openclamdblas_fn12(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } \ - -#define openclamdblas_fn13(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } \ - -#define openclamdblas_fn14(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } \ - -#define openclamdblas_fn15(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } \ - -#define openclamdblas_fn16(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } \ - -#define openclamdblas_fn17(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17); } \ - -#define openclamdblas_fn18(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18); } \ - -#define openclamdblas_fn19(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19); } \ - -#define openclamdblas_fn20(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); } \ - -#define openclamdblas_fn21(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21); } \ - -#define openclamdblas_fn22(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22); } \ - -} - -// generated by parser_clamdblas.py -//openclamdblas_fn4(OPENCLAMDBLAS_FN_clAmdBlasAddScratchImage, cl_ulong, (cl_context p1, size_t p2, size_t p3, clAmdBlasStatus* p4)) -//cl_ulong (*clAmdBlasAddScratchImage)(cl_context, size_t, size_t, clAmdBlasStatus*) = -// OPENCLAMDBLAS_FN_clAmdBlasAddScratchImage_switch_fn; -//static const struct DynamicFnEntry clAmdBlasAddScratchImage_definition = { "clAmdBlasAddScratchImage", (void**)&clAmdBlasAddScratchImage}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasCaxpy, clAmdBlasStatus, (size_t p1, cl_float2 p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasCaxpy)(size_t, cl_float2, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCaxpy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCaxpy_definition = { "clAmdBlasCaxpy", (void**)&clAmdBlasCaxpy}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasCcopy, clAmdBlasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasCcopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCcopy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCcopy_definition = { "clAmdBlasCcopy", (void**)&clAmdBlasCcopy}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasCdotc, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasCdotc)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCdotc_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCdotc_definition = { "clAmdBlasCdotc", (void**)&clAmdBlasCdotc}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasCdotu, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasCdotu)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCdotu_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCdotu_definition = { "clAmdBlasCdotu", (void**)&clAmdBlasCdotu}; - -//openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasCgbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_float2 p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_float2 p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -//clAmdBlasStatus (*clAmdBlasCgbmv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCgbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCgbmv_definition = { "clAmdBlasCgbmv", (void**)&clAmdBlasCgbmv}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasCgemm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, FloatComplex p7, const cl_mem p8, size_t p9, const cl_mem p10, size_t p11, FloatComplex p12, cl_mem p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasCgemm)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, FloatComplex, const cl_mem, size_t, const cl_mem, size_t, FloatComplex, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCgemm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCgemm_definition = { "clAmdBlasCgemm", (void**)&clAmdBlasCgemm}; - -openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasCgemmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, FloatComplex p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, FloatComplex p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -clAmdBlasStatus (*clAmdBlasCgemmEx)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, FloatComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = - OPENCLAMDBLAS_FN_clAmdBlasCgemmEx_switch_fn; -static const struct DynamicFnEntry clAmdBlasCgemmEx_definition = { "clAmdBlasCgemmEx", (void**)&clAmdBlasCgemmEx}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasCgemv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, FloatComplex p5, const cl_mem p6, size_t p7, const cl_mem p8, size_t p9, int p10, FloatComplex p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasCgemv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, const cl_mem, size_t, int, FloatComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCgemv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCgemv_definition = { "clAmdBlasCgemv", (void**)&clAmdBlasCgemv}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasCgemvEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, FloatComplex p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, FloatComplex p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasCgemvEx)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, FloatComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCgemvEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCgemvEx_definition = { "clAmdBlasCgemvEx", (void**)&clAmdBlasCgemvEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCgerc, clAmdBlasStatus, (clAmdBlasOrder p1, size_t p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCgerc)(clAmdBlasOrder, size_t, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCgerc_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCgerc_definition = { "clAmdBlasCgerc", (void**)&clAmdBlasCgerc}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCgeru, clAmdBlasStatus, (clAmdBlasOrder p1, size_t p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCgeru)(clAmdBlasOrder, size_t, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCgeru_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCgeru_definition = { "clAmdBlasCgeru", (void**)&clAmdBlasCgeru}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasChbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, size_t p4, cl_float2 p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_float2 p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasChbmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasChbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasChbmv_definition = { "clAmdBlasChbmv", (void**)&clAmdBlasChbmv}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasChemm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, size_t p4, size_t p5, cl_float2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasChemm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasChemm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasChemm_definition = { "clAmdBlasChemm", (void**)&clAmdBlasChemm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasChemv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, FloatComplex p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, FloatComplex p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasChemv)(clAmdBlasOrder, clAmdBlasUplo, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, FloatComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasChemv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasChemv_definition = { "clAmdBlasChemv", (void**)&clAmdBlasChemv}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasCher, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasCher)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCher_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCher_definition = { "clAmdBlasCher", (void**)&clAmdBlasCher}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCher2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCher2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCher2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCher2_definition = { "clAmdBlasCher2", (void**)&clAmdBlasCher2}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasCher2k, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasCher2k)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCher2k_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCher2k_definition = { "clAmdBlasCher2k", (void**)&clAmdBlasCher2k}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCherk, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, float p6, const cl_mem p7, size_t p8, size_t p9, float p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCherk)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, float, const cl_mem, size_t, size_t, float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCherk_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCherk_definition = { "clAmdBlasCherk", (void**)&clAmdBlasCherk}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasChpmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_float2 p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasChpmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float2, const cl_mem, size_t, const cl_mem, size_t, int, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasChpmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasChpmv_definition = { "clAmdBlasChpmv", (void**)&clAmdBlasChpmv}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasChpr, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasChpr)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasChpr_switch_fn; -//static const struct DynamicFnEntry clAmdBlasChpr_definition = { "clAmdBlasChpr", (void**)&clAmdBlasChpr}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasChpr2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasChpr2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasChpr2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasChpr2_definition = { "clAmdBlasChpr2", (void**)&clAmdBlasChpr2}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasCrotg, clAmdBlasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasCrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCrotg_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCrotg_definition = { "clAmdBlasCrotg", (void**)&clAmdBlasCrotg}; - -//openclamdblas_fn10(OPENCLAMDBLAS_FN_clAmdBlasCscal, clAmdBlasStatus, (size_t p1, cl_float2 p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) -//clAmdBlasStatus (*clAmdBlasCscal)(size_t, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCscal_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCscal_definition = { "clAmdBlasCscal", (void**)&clAmdBlasCscal}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasCsrot, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_float p8, cl_float p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasCsrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_float, cl_float, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsrot_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsrot_definition = { "clAmdBlasCsrot", (void**)&clAmdBlasCsrot}; - -//openclamdblas_fn10(OPENCLAMDBLAS_FN_clAmdBlasCsscal, clAmdBlasStatus, (size_t p1, cl_float p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) -//clAmdBlasStatus (*clAmdBlasCsscal)(size_t, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsscal_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsscal_definition = { "clAmdBlasCsscal", (void**)&clAmdBlasCsscal}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasCswap, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasCswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCswap_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCswap_definition = { "clAmdBlasCswap", (void**)&clAmdBlasCswap}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasCsymm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, size_t p4, size_t p5, cl_float2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasCsymm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsymm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsymm_definition = { "clAmdBlasCsymm", (void**)&clAmdBlasCsymm}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCsyr2k, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, const cl_mem p9, size_t p10, FloatComplex p11, cl_mem p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCsyr2k)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, const cl_mem, size_t, FloatComplex, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsyr2k_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsyr2k_definition = { "clAmdBlasCsyr2k", (void**)&clAmdBlasCsyr2k}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasCsyr2kEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, FloatComplex p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasCsyr2kEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, FloatComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsyr2kEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsyr2kEx_definition = { "clAmdBlasCsyr2kEx", (void**)&clAmdBlasCsyr2kEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasCsyrk, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, FloatComplex p9, cl_mem p10, size_t p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasCsyrk)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, FloatComplex, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsyrk_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsyrk_definition = { "clAmdBlasCsyrk", (void**)&clAmdBlasCsyrk}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCsyrkEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, size_t p9, FloatComplex p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCsyrkEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, FloatComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCsyrkEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCsyrkEx_definition = { "clAmdBlasCsyrkEx", (void**)&clAmdBlasCsyrkEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasCtbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasCtbmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtbmv_definition = { "clAmdBlasCtbmv", (void**)&clAmdBlasCtbmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasCtbsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasCtbsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtbsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtbsv_definition = { "clAmdBlasCtbsv", (void**)&clAmdBlasCtbsv}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasCtpmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasCtpmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtpmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtpmv_definition = { "clAmdBlasCtpmv", (void**)&clAmdBlasCtpmv}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasCtpsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasCtpsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtpsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtpsv_definition = { "clAmdBlasCtpsv", (void**)&clAmdBlasCtpsv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasCtrmm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, FloatComplex p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasCtrmm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, FloatComplex, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtrmm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtrmm_definition = { "clAmdBlasCtrmm", (void**)&clAmdBlasCtrmm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasCtrmmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, FloatComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasCtrmmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtrmmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtrmmEx_definition = { "clAmdBlasCtrmmEx", (void**)&clAmdBlasCtrmmEx}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasCtrmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasCtrmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtrmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtrmv_definition = { "clAmdBlasCtrmv", (void**)&clAmdBlasCtrmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasCtrsm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, FloatComplex p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasCtrsm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, FloatComplex, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtrsm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtrsm_definition = { "clAmdBlasCtrsm", (void**)&clAmdBlasCtrsm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasCtrsmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, FloatComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasCtrsmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtrsmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtrsmEx_definition = { "clAmdBlasCtrsmEx", (void**)&clAmdBlasCtrsmEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasCtrsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasCtrsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasCtrsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasCtrsv_definition = { "clAmdBlasCtrsv", (void**)&clAmdBlasCtrsv}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasDasum, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasDasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDasum_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDasum_definition = { "clAmdBlasDasum", (void**)&clAmdBlasDasum}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasDaxpy, clAmdBlasStatus, (size_t p1, cl_double p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasDaxpy)(size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDaxpy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDaxpy_definition = { "clAmdBlasDaxpy", (void**)&clAmdBlasDaxpy}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasDcopy, clAmdBlasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasDcopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDcopy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDcopy_definition = { "clAmdBlasDcopy", (void**)&clAmdBlasDcopy}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasDdot, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasDdot)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDdot_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDdot_definition = { "clAmdBlasDdot", (void**)&clAmdBlasDdot}; - -//openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasDgbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_double p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_double p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -//clAmdBlasStatus (*clAmdBlasDgbmv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDgbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDgbmv_definition = { "clAmdBlasDgbmv", (void**)&clAmdBlasDgbmv}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasDgemm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, cl_double p7, const cl_mem p8, size_t p9, const cl_mem p10, size_t p11, cl_double p12, cl_mem p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasDgemm)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, cl_double, const cl_mem, size_t, const cl_mem, size_t, cl_double, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDgemm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDgemm_definition = { "clAmdBlasDgemm", (void**)&clAmdBlasDgemm}; - -openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasDgemmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, cl_double p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, cl_double p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -clAmdBlasStatus (*clAmdBlasDgemmEx)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = - OPENCLAMDBLAS_FN_clAmdBlasDgemmEx_switch_fn; -static const struct DynamicFnEntry clAmdBlasDgemmEx_definition = { "clAmdBlasDgemmEx", (void**)&clAmdBlasDgemmEx}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasDgemv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, cl_double p5, const cl_mem p6, size_t p7, const cl_mem p8, size_t p9, int p10, cl_double p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasDgemv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDgemv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDgemv_definition = { "clAmdBlasDgemv", (void**)&clAmdBlasDgemv}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasDgemvEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, cl_double p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_double p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasDgemvEx)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDgemvEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDgemvEx_definition = { "clAmdBlasDgemvEx", (void**)&clAmdBlasDgemvEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDger, clAmdBlasStatus, (clAmdBlasOrder p1, size_t p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDger)(clAmdBlasOrder, size_t, size_t, cl_double, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDger_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDger_definition = { "clAmdBlasDger", (void**)&clAmdBlasDger}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasDnrm2, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasDnrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDnrm2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDnrm2_definition = { "clAmdBlasDnrm2", (void**)&clAmdBlasDnrm2}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasDrot, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_double p8, cl_double p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasDrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_double, cl_double, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDrot_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDrot_definition = { "clAmdBlasDrot", (void**)&clAmdBlasDrot}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasDrotg, clAmdBlasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasDrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDrotg_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDrotg_definition = { "clAmdBlasDrotg", (void**)&clAmdBlasDrotg}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasDrotm, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasDrotm)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, const cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDrotm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDrotm_definition = { "clAmdBlasDrotm", (void**)&clAmdBlasDrotm}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasDrotmg, clAmdBlasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, const cl_mem p7, size_t p8, cl_mem p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasDrotmg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDrotmg_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDrotmg_definition = { "clAmdBlasDrotmg", (void**)&clAmdBlasDrotmg}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasDsbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, size_t p4, cl_double p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_double p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasDsbmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsbmv_definition = { "clAmdBlasDsbmv", (void**)&clAmdBlasDsbmv}; - -//openclamdblas_fn10(OPENCLAMDBLAS_FN_clAmdBlasDscal, clAmdBlasStatus, (size_t p1, cl_double p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) -//clAmdBlasStatus (*clAmdBlasDscal)(size_t, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDscal_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDscal_definition = { "clAmdBlasDscal", (void**)&clAmdBlasDscal}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDspmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_double p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDspmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDspmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDspmv_definition = { "clAmdBlasDspmv", (void**)&clAmdBlasDspmv}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasDspr, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasDspr)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDspr_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDspr_definition = { "clAmdBlasDspr", (void**)&clAmdBlasDspr}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasDspr2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasDspr2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDspr2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDspr2_definition = { "clAmdBlasDspr2", (void**)&clAmdBlasDspr2}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasDswap, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasDswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDswap_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDswap_definition = { "clAmdBlasDswap", (void**)&clAmdBlasDswap}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasDsymm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasDsymm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsymm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsymm_definition = { "clAmdBlasDsymm", (void**)&clAmdBlasDsymm}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDsymv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_double p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDsymv)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsymv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsymv_definition = { "clAmdBlasDsymv", (void**)&clAmdBlasDsymv}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasDsymvEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, cl_double p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasDsymvEx)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsymvEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsymvEx_definition = { "clAmdBlasDsymvEx", (void**)&clAmdBlasDsymvEx}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasDsyr, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasDsyr)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsyr_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsyr_definition = { "clAmdBlasDsyr", (void**)&clAmdBlasDsyr}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDsyr2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDsyr2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsyr2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsyr2_definition = { "clAmdBlasDsyr2", (void**)&clAmdBlasDsyr2}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDsyr2k, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, const cl_mem p9, size_t p10, cl_double p11, cl_mem p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDsyr2k)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, const cl_mem, size_t, cl_double, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsyr2k_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsyr2k_definition = { "clAmdBlasDsyr2k", (void**)&clAmdBlasDsyr2k}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasDsyr2kEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasDsyr2kEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsyr2kEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsyr2kEx_definition = { "clAmdBlasDsyr2kEx", (void**)&clAmdBlasDsyr2kEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasDsyrk, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, cl_double p9, cl_mem p10, size_t p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasDsyrk)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, cl_double, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsyrk_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsyrk_definition = { "clAmdBlasDsyrk", (void**)&clAmdBlasDsyrk}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDsyrkEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, size_t p9, cl_double p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDsyrkEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDsyrkEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDsyrkEx_definition = { "clAmdBlasDsyrkEx", (void**)&clAmdBlasDsyrkEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasDtbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasDtbmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtbmv_definition = { "clAmdBlasDtbmv", (void**)&clAmdBlasDtbmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasDtbsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasDtbsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtbsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtbsv_definition = { "clAmdBlasDtbsv", (void**)&clAmdBlasDtbsv}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasDtpmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasDtpmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtpmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtpmv_definition = { "clAmdBlasDtpmv", (void**)&clAmdBlasDtpmv}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasDtpsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasDtpsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtpsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtpsv_definition = { "clAmdBlasDtpsv", (void**)&clAmdBlasDtpsv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasDtrmm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_double p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasDtrmm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_double, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtrmm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtrmm_definition = { "clAmdBlasDtrmm", (void**)&clAmdBlasDtrmm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasDtrmmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_double p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasDtrmmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_double, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtrmmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtrmmEx_definition = { "clAmdBlasDtrmmEx", (void**)&clAmdBlasDtrmmEx}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasDtrmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasDtrmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtrmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtrmv_definition = { "clAmdBlasDtrmv", (void**)&clAmdBlasDtrmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasDtrsm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_double p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasDtrsm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_double, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtrsm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtrsm_definition = { "clAmdBlasDtrsm", (void**)&clAmdBlasDtrsm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasDtrsmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_double p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasDtrsmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_double, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtrsmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtrsmEx_definition = { "clAmdBlasDtrsmEx", (void**)&clAmdBlasDtrsmEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasDtrsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasDtrsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDtrsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDtrsv_definition = { "clAmdBlasDtrsv", (void**)&clAmdBlasDtrsv}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasDzasum, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasDzasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDzasum_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDzasum_definition = { "clAmdBlasDzasum", (void**)&clAmdBlasDzasum}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasDznrm2, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasDznrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasDznrm2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasDznrm2_definition = { "clAmdBlasDznrm2", (void**)&clAmdBlasDznrm2}; - -//openclamdblas_fn3(OPENCLAMDBLAS_FN_clAmdBlasGetVersion, clAmdBlasStatus, (cl_uint* p1, cl_uint* p2, cl_uint* p3)) -//clAmdBlasStatus (*clAmdBlasGetVersion)(cl_uint*, cl_uint*, cl_uint*) = -// OPENCLAMDBLAS_FN_clAmdBlasGetVersion_switch_fn; -//static const struct DynamicFnEntry clAmdBlasGetVersion_definition = { "clAmdBlasGetVersion", (void**)&clAmdBlasGetVersion}; - -//openclamdblas_fn1(OPENCLAMDBLAS_FN_clAmdBlasRemoveScratchImage, clAmdBlasStatus, (cl_ulong p1)) -//clAmdBlasStatus (*clAmdBlasRemoveScratchImage)(cl_ulong) = -// OPENCLAMDBLAS_FN_clAmdBlasRemoveScratchImage_switch_fn; -//static const struct DynamicFnEntry clAmdBlasRemoveScratchImage_definition = { "clAmdBlasRemoveScratchImage", (void**)&clAmdBlasRemoveScratchImage}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasSasum, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasSasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSasum_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSasum_definition = { "clAmdBlasSasum", (void**)&clAmdBlasSasum}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasSaxpy, clAmdBlasStatus, (size_t p1, cl_float p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasSaxpy)(size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSaxpy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSaxpy_definition = { "clAmdBlasSaxpy", (void**)&clAmdBlasSaxpy}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasScasum, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasScasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasScasum_switch_fn; -//static const struct DynamicFnEntry clAmdBlasScasum_definition = { "clAmdBlasScasum", (void**)&clAmdBlasScasum}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasScnrm2, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasScnrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasScnrm2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasScnrm2_definition = { "clAmdBlasScnrm2", (void**)&clAmdBlasScnrm2}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasScopy, clAmdBlasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasScopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasScopy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasScopy_definition = { "clAmdBlasScopy", (void**)&clAmdBlasScopy}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasSdot, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasSdot)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSdot_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSdot_definition = { "clAmdBlasSdot", (void**)&clAmdBlasSdot}; - -openclamdblas_fn0(OPENCLAMDBLAS_FN_clAmdBlasSetup, clAmdBlasStatus, ()) -clAmdBlasStatus (*clAmdBlasSetup)() = - OPENCLAMDBLAS_FN_clAmdBlasSetup_switch_fn; -static const struct DynamicFnEntry clAmdBlasSetup_definition = { "clAmdBlasSetup", (void**)&clAmdBlasSetup}; - -//openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasSgbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_float p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_float p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -//clAmdBlasStatus (*clAmdBlasSgbmv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSgbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSgbmv_definition = { "clAmdBlasSgbmv", (void**)&clAmdBlasSgbmv}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasSgemm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, cl_float p7, const cl_mem p8, size_t p9, const cl_mem p10, size_t p11, cl_float p12, cl_mem p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasSgemm)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, cl_float, const cl_mem, size_t, const cl_mem, size_t, cl_float, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSgemm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSgemm_definition = { "clAmdBlasSgemm", (void**)&clAmdBlasSgemm}; - -openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasSgemmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, cl_float p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, cl_float p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -clAmdBlasStatus (*clAmdBlasSgemmEx)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = - OPENCLAMDBLAS_FN_clAmdBlasSgemmEx_switch_fn; -static const struct DynamicFnEntry clAmdBlasSgemmEx_definition = { "clAmdBlasSgemmEx", (void**)&clAmdBlasSgemmEx}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasSgemv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, cl_float p5, const cl_mem p6, size_t p7, const cl_mem p8, size_t p9, int p10, cl_float p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasSgemv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSgemv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSgemv_definition = { "clAmdBlasSgemv", (void**)&clAmdBlasSgemv}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasSgemvEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, cl_float p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_float p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasSgemvEx)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSgemvEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSgemvEx_definition = { "clAmdBlasSgemvEx", (void**)&clAmdBlasSgemvEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasSger, clAmdBlasStatus, (clAmdBlasOrder p1, size_t p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasSger)(clAmdBlasOrder, size_t, size_t, cl_float, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSger_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSger_definition = { "clAmdBlasSger", (void**)&clAmdBlasSger}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasSnrm2, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasSnrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSnrm2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSnrm2_definition = { "clAmdBlasSnrm2", (void**)&clAmdBlasSnrm2}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasSrot, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_float p8, cl_float p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasSrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_float, cl_float, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSrot_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSrot_definition = { "clAmdBlasSrot", (void**)&clAmdBlasSrot}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasSrotg, clAmdBlasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasSrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSrotg_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSrotg_definition = { "clAmdBlasSrotg", (void**)&clAmdBlasSrotg}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasSrotm, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasSrotm)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, const cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSrotm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSrotm_definition = { "clAmdBlasSrotm", (void**)&clAmdBlasSrotm}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasSrotmg, clAmdBlasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, const cl_mem p7, size_t p8, cl_mem p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasSrotmg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSrotmg_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSrotmg_definition = { "clAmdBlasSrotmg", (void**)&clAmdBlasSrotmg}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasSsbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, size_t p4, cl_float p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_float p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasSsbmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsbmv_definition = { "clAmdBlasSsbmv", (void**)&clAmdBlasSsbmv}; - -//openclamdblas_fn10(OPENCLAMDBLAS_FN_clAmdBlasSscal, clAmdBlasStatus, (size_t p1, cl_float p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) -//clAmdBlasStatus (*clAmdBlasSscal)(size_t, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSscal_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSscal_definition = { "clAmdBlasSscal", (void**)&clAmdBlasSscal}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasSspmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_float p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasSspmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSspmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSspmv_definition = { "clAmdBlasSspmv", (void**)&clAmdBlasSspmv}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasSspr, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasSspr)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSspr_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSspr_definition = { "clAmdBlasSspr", (void**)&clAmdBlasSspr}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasSspr2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasSspr2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSspr2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSspr2_definition = { "clAmdBlasSspr2", (void**)&clAmdBlasSspr2}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasSswap, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasSswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSswap_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSswap_definition = { "clAmdBlasSswap", (void**)&clAmdBlasSswap}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasSsymm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasSsymm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsymm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsymm_definition = { "clAmdBlasSsymm", (void**)&clAmdBlasSsymm}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasSsymv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_float p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasSsymv)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsymv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsymv_definition = { "clAmdBlasSsymv", (void**)&clAmdBlasSsymv}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasSsymvEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, cl_float p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasSsymvEx)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsymvEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsymvEx_definition = { "clAmdBlasSsymvEx", (void**)&clAmdBlasSsymvEx}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasSsyr, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasSsyr)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsyr_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsyr_definition = { "clAmdBlasSsyr", (void**)&clAmdBlasSsyr}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasSsyr2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasSsyr2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_float, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsyr2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsyr2_definition = { "clAmdBlasSsyr2", (void**)&clAmdBlasSsyr2}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasSsyr2k, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, const cl_mem p9, size_t p10, cl_float p11, cl_mem p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasSsyr2k)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, const cl_mem, size_t, cl_float, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsyr2k_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsyr2k_definition = { "clAmdBlasSsyr2k", (void**)&clAmdBlasSsyr2k}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasSsyr2kEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasSsyr2kEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsyr2kEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsyr2kEx_definition = { "clAmdBlasSsyr2kEx", (void**)&clAmdBlasSsyr2kEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasSsyrk, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, cl_float p9, cl_mem p10, size_t p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasSsyrk)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, cl_float, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsyrk_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsyrk_definition = { "clAmdBlasSsyrk", (void**)&clAmdBlasSsyrk}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasSsyrkEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, size_t p9, cl_float p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasSsyrkEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasSsyrkEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasSsyrkEx_definition = { "clAmdBlasSsyrkEx", (void**)&clAmdBlasSsyrkEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasStbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasStbmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStbmv_definition = { "clAmdBlasStbmv", (void**)&clAmdBlasStbmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasStbsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasStbsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStbsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStbsv_definition = { "clAmdBlasStbsv", (void**)&clAmdBlasStbsv}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasStpmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasStpmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStpmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStpmv_definition = { "clAmdBlasStpmv", (void**)&clAmdBlasStpmv}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasStpsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasStpsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStpsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStpsv_definition = { "clAmdBlasStpsv", (void**)&clAmdBlasStpsv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasStrmm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_float p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasStrmm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_float, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStrmm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStrmm_definition = { "clAmdBlasStrmm", (void**)&clAmdBlasStrmm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasStrmmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_float p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasStrmmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_float, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStrmmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStrmmEx_definition = { "clAmdBlasStrmmEx", (void**)&clAmdBlasStrmmEx}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasStrmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasStrmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStrmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStrmv_definition = { "clAmdBlasStrmv", (void**)&clAmdBlasStrmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasStrsm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_float p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasStrsm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_float, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStrsm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStrsm_definition = { "clAmdBlasStrsm", (void**)&clAmdBlasStrsm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasStrsmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, cl_float p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasStrsmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, cl_float, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStrsmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStrsmEx_definition = { "clAmdBlasStrsmEx", (void**)&clAmdBlasStrsmEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasStrsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasStrsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasStrsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasStrsv_definition = { "clAmdBlasStrsv", (void**)&clAmdBlasStrsv}; - -openclamdblas_fn0(OPENCLAMDBLAS_FN_clAmdBlasTeardown, void, ()) -void (*clAmdBlasTeardown)() = - OPENCLAMDBLAS_FN_clAmdBlasTeardown_switch_fn; -static const struct DynamicFnEntry clAmdBlasTeardown_definition = { "clAmdBlasTeardown", (void**)&clAmdBlasTeardown}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasZaxpy, clAmdBlasStatus, (size_t p1, cl_double2 p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasZaxpy)(size_t, cl_double2, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZaxpy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZaxpy_definition = { "clAmdBlasZaxpy", (void**)&clAmdBlasZaxpy}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasZcopy, clAmdBlasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasZcopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZcopy_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZcopy_definition = { "clAmdBlasZcopy", (void**)&clAmdBlasZcopy}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasZdotc, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasZdotc)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZdotc_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZdotc_definition = { "clAmdBlasZdotc", (void**)&clAmdBlasZdotc}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasZdotu, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasZdotu)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZdotu_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZdotu_definition = { "clAmdBlasZdotu", (void**)&clAmdBlasZdotu}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasZdrot, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_double p8, cl_double p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasZdrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_double, cl_double, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZdrot_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZdrot_definition = { "clAmdBlasZdrot", (void**)&clAmdBlasZdrot}; - -//openclamdblas_fn10(OPENCLAMDBLAS_FN_clAmdBlasZdscal, clAmdBlasStatus, (size_t p1, cl_double p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) -//clAmdBlasStatus (*clAmdBlasZdscal)(size_t, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZdscal_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZdscal_definition = { "clAmdBlasZdscal", (void**)&clAmdBlasZdscal}; - -//openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasZgbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_double2 p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_double2 p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -//clAmdBlasStatus (*clAmdBlasZgbmv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZgbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZgbmv_definition = { "clAmdBlasZgbmv", (void**)&clAmdBlasZgbmv}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasZgemm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, DoubleComplex p7, const cl_mem p8, size_t p9, const cl_mem p10, size_t p11, DoubleComplex p12, cl_mem p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasZgemm)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, DoubleComplex, const cl_mem, size_t, const cl_mem, size_t, DoubleComplex, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZgemm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZgemm_definition = { "clAmdBlasZgemm", (void**)&clAmdBlasZgemm}; - -openclamdblas_fn22(OPENCLAMDBLAS_FN_clAmdBlasZgemmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, clAmdBlasTranspose p3, size_t p4, size_t p5, size_t p6, DoubleComplex p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, DoubleComplex p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) -clAmdBlasStatus (*clAmdBlasZgemmEx)(clAmdBlasOrder, clAmdBlasTranspose, clAmdBlasTranspose, size_t, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, DoubleComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = - OPENCLAMDBLAS_FN_clAmdBlasZgemmEx_switch_fn; -static const struct DynamicFnEntry clAmdBlasZgemmEx_definition = { "clAmdBlasZgemmEx", (void**)&clAmdBlasZgemmEx}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasZgemv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, DoubleComplex p5, const cl_mem p6, size_t p7, const cl_mem p8, size_t p9, int p10, DoubleComplex p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasZgemv)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, const cl_mem, size_t, int, DoubleComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZgemv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZgemv_definition = { "clAmdBlasZgemv", (void**)&clAmdBlasZgemv}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasZgemvEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasTranspose p2, size_t p3, size_t p4, DoubleComplex p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, DoubleComplex p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasZgemvEx)(clAmdBlasOrder, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, DoubleComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZgemvEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZgemvEx_definition = { "clAmdBlasZgemvEx", (void**)&clAmdBlasZgemvEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZgerc, clAmdBlasStatus, (clAmdBlasOrder p1, size_t p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZgerc)(clAmdBlasOrder, size_t, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZgerc_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZgerc_definition = { "clAmdBlasZgerc", (void**)&clAmdBlasZgerc}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZgeru, clAmdBlasStatus, (clAmdBlasOrder p1, size_t p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZgeru)(clAmdBlasOrder, size_t, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZgeru_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZgeru_definition = { "clAmdBlasZgeru", (void**)&clAmdBlasZgeru}; - -//openclamdblas_fn20(OPENCLAMDBLAS_FN_clAmdBlasZhbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, size_t p4, cl_double2 p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_double2 p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) -//clAmdBlasStatus (*clAmdBlasZhbmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZhbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZhbmv_definition = { "clAmdBlasZhbmv", (void**)&clAmdBlasZhbmv}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasZhemm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, size_t p4, size_t p5, cl_double2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasZhemm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZhemm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZhemm_definition = { "clAmdBlasZhemm", (void**)&clAmdBlasZhemm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasZhemv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, DoubleComplex p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, DoubleComplex p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasZhemv)(clAmdBlasOrder, clAmdBlasUplo, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, DoubleComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZhemv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZhemv_definition = { "clAmdBlasZhemv", (void**)&clAmdBlasZhemv}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasZher, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasZher)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZher_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZher_definition = { "clAmdBlasZher", (void**)&clAmdBlasZher}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZher2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZher2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZher2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZher2_definition = { "clAmdBlasZher2", (void**)&clAmdBlasZher2}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasZher2k, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasZher2k)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZher2k_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZher2k_definition = { "clAmdBlasZher2k", (void**)&clAmdBlasZher2k}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZherk, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, double p6, const cl_mem p7, size_t p8, size_t p9, double p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZherk)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, double, const cl_mem, size_t, size_t, double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZherk_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZherk_definition = { "clAmdBlasZherk", (void**)&clAmdBlasZherk}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZhpmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_double2 p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZhpmv)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double2, const cl_mem, size_t, const cl_mem, size_t, int, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZhpmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZhpmv_definition = { "clAmdBlasZhpmv", (void**)&clAmdBlasZhpmv}; - -//openclamdblas_fn14(OPENCLAMDBLAS_FN_clAmdBlasZhpr, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) -//clAmdBlasStatus (*clAmdBlasZhpr)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZhpr_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZhpr_definition = { "clAmdBlasZhpr", (void**)&clAmdBlasZhpr}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasZhpr2, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasZhpr2)(clAmdBlasOrder, clAmdBlasUplo, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZhpr2_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZhpr2_definition = { "clAmdBlasZhpr2", (void**)&clAmdBlasZhpr2}; - -//openclamdblas_fn13(OPENCLAMDBLAS_FN_clAmdBlasZrotg, clAmdBlasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) -//clAmdBlasStatus (*clAmdBlasZrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZrotg_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZrotg_definition = { "clAmdBlasZrotg", (void**)&clAmdBlasZrotg}; - -//openclamdblas_fn10(OPENCLAMDBLAS_FN_clAmdBlasZscal, clAmdBlasStatus, (size_t p1, cl_double2 p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) -//clAmdBlasStatus (*clAmdBlasZscal)(size_t, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZscal_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZscal_definition = { "clAmdBlasZscal", (void**)&clAmdBlasZscal}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasZswap, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasZswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZswap_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZswap_definition = { "clAmdBlasZswap", (void**)&clAmdBlasZswap}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasZsymm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, size_t p4, size_t p5, cl_double2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasZsymm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZsymm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZsymm_definition = { "clAmdBlasZsymm", (void**)&clAmdBlasZsymm}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZsyr2k, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, const cl_mem p9, size_t p10, DoubleComplex p11, cl_mem p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZsyr2k)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, const cl_mem, size_t, DoubleComplex, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZsyr2k_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZsyr2k_definition = { "clAmdBlasZsyr2k", (void**)&clAmdBlasZsyr2k}; - -//openclamdblas_fn21(OPENCLAMDBLAS_FN_clAmdBlasZsyr2kEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, DoubleComplex p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) -//clAmdBlasStatus (*clAmdBlasZsyr2kEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, DoubleComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZsyr2kEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZsyr2kEx_definition = { "clAmdBlasZsyr2kEx", (void**)&clAmdBlasZsyr2kEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasZsyrk, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, DoubleComplex p9, cl_mem p10, size_t p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasZsyrk)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, DoubleComplex, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZsyrk_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZsyrk_definition = { "clAmdBlasZsyrk", (void**)&clAmdBlasZsyrk}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZsyrkEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, size_t p9, DoubleComplex p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZsyrkEx)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, DoubleComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZsyrkEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZsyrkEx_definition = { "clAmdBlasZsyrkEx", (void**)&clAmdBlasZsyrkEx}; - -//openclamdblas_fn18(OPENCLAMDBLAS_FN_clAmdBlasZtbmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) -//clAmdBlasStatus (*clAmdBlasZtbmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtbmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtbmv_definition = { "clAmdBlasZtbmv", (void**)&clAmdBlasZtbmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasZtbsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasZtbsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtbsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtbsv_definition = { "clAmdBlasZtbsv", (void**)&clAmdBlasZtbsv}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasZtpmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasZtpmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtpmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtpmv_definition = { "clAmdBlasZtpmv", (void**)&clAmdBlasZtpmv}; - -//openclamdblas_fn15(OPENCLAMDBLAS_FN_clAmdBlasZtpsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) -//clAmdBlasStatus (*clAmdBlasZtpsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtpsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtpsv_definition = { "clAmdBlasZtpsv", (void**)&clAmdBlasZtpsv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasZtrmm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, DoubleComplex p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasZtrmm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, DoubleComplex, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtrmm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtrmm_definition = { "clAmdBlasZtrmm", (void**)&clAmdBlasZtrmm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasZtrmmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, DoubleComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasZtrmmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtrmmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtrmmEx_definition = { "clAmdBlasZtrmmEx", (void**)&clAmdBlasZtrmmEx}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasZtrmv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasZtrmv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtrmv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtrmv_definition = { "clAmdBlasZtrmv", (void**)&clAmdBlasZtrmv}; - -//openclamdblas_fn17(OPENCLAMDBLAS_FN_clAmdBlasZtrsm, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, DoubleComplex p8, const cl_mem p9, size_t p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) -//clAmdBlasStatus (*clAmdBlasZtrsm)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, DoubleComplex, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtrsm_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtrsm_definition = { "clAmdBlasZtrsm", (void**)&clAmdBlasZtrsm}; - -//openclamdblas_fn19(OPENCLAMDBLAS_FN_clAmdBlasZtrsmEx, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasSide p2, clAmdBlasUplo p3, clAmdBlasTranspose p4, clAmdBlasDiag p5, size_t p6, size_t p7, DoubleComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) -//clAmdBlasStatus (*clAmdBlasZtrsmEx)(clAmdBlasOrder, clAmdBlasSide, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtrsmEx_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtrsmEx_definition = { "clAmdBlasZtrsmEx", (void**)&clAmdBlasZtrsmEx}; - -//openclamdblas_fn16(OPENCLAMDBLAS_FN_clAmdBlasZtrsv, clAmdBlasStatus, (clAmdBlasOrder p1, clAmdBlasUplo p2, clAmdBlasTranspose p3, clAmdBlasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) -//clAmdBlasStatus (*clAmdBlasZtrsv)(clAmdBlasOrder, clAmdBlasUplo, clAmdBlasTranspose, clAmdBlasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasZtrsv_switch_fn; -//static const struct DynamicFnEntry clAmdBlasZtrsv_definition = { "clAmdBlasZtrsv", (void**)&clAmdBlasZtrsv}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasiCamax, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasiCamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasiCamax_switch_fn; -//static const struct DynamicFnEntry clAmdBlasiCamax_definition = { "clAmdBlasiCamax", (void**)&clAmdBlasiCamax}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasiDamax, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasiDamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasiDamax_switch_fn; -//static const struct DynamicFnEntry clAmdBlasiDamax_definition = { "clAmdBlasiDamax", (void**)&clAmdBlasiDamax}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasiSamax, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasiSamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasiSamax_switch_fn; -//static const struct DynamicFnEntry clAmdBlasiSamax_definition = { "clAmdBlasiSamax", (void**)&clAmdBlasiSamax}; - -//openclamdblas_fn12(OPENCLAMDBLAS_FN_clAmdBlasiZamax, clAmdBlasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) -//clAmdBlasStatus (*clAmdBlasiZamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = -// OPENCLAMDBLAS_FN_clAmdBlasiZamax_switch_fn; -//static const struct DynamicFnEntry clAmdBlasiZamax_definition = { "clAmdBlasiZamax", (void**)&clAmdBlasiZamax}; - - -// generated by parser_clamdblas.py -static const struct DynamicFnEntry* openclamdblas_fn[] = { - NULL/*&clAmdBlasAddScratchImage_definition*/, - NULL/*&clAmdBlasCaxpy_definition*/, - NULL/*&clAmdBlasCcopy_definition*/, - NULL/*&clAmdBlasCdotc_definition*/, - NULL/*&clAmdBlasCdotu_definition*/, - NULL/*&clAmdBlasCgbmv_definition*/, - NULL/*&clAmdBlasCgemm_definition*/, - &clAmdBlasCgemmEx_definition, - NULL/*&clAmdBlasCgemv_definition*/, - NULL/*&clAmdBlasCgemvEx_definition*/, - NULL/*&clAmdBlasCgerc_definition*/, - NULL/*&clAmdBlasCgeru_definition*/, - NULL/*&clAmdBlasChbmv_definition*/, - NULL/*&clAmdBlasChemm_definition*/, - NULL/*&clAmdBlasChemv_definition*/, - NULL/*&clAmdBlasCher_definition*/, - NULL/*&clAmdBlasCher2_definition*/, - NULL/*&clAmdBlasCher2k_definition*/, - NULL/*&clAmdBlasCherk_definition*/, - NULL/*&clAmdBlasChpmv_definition*/, - NULL/*&clAmdBlasChpr_definition*/, - NULL/*&clAmdBlasChpr2_definition*/, - NULL/*&clAmdBlasCrotg_definition*/, - NULL/*&clAmdBlasCscal_definition*/, - NULL/*&clAmdBlasCsrot_definition*/, - NULL/*&clAmdBlasCsscal_definition*/, - NULL/*&clAmdBlasCswap_definition*/, - NULL/*&clAmdBlasCsymm_definition*/, - NULL/*&clAmdBlasCsyr2k_definition*/, - NULL/*&clAmdBlasCsyr2kEx_definition*/, - NULL/*&clAmdBlasCsyrk_definition*/, - NULL/*&clAmdBlasCsyrkEx_definition*/, - NULL/*&clAmdBlasCtbmv_definition*/, - NULL/*&clAmdBlasCtbsv_definition*/, - NULL/*&clAmdBlasCtpmv_definition*/, - NULL/*&clAmdBlasCtpsv_definition*/, - NULL/*&clAmdBlasCtrmm_definition*/, - NULL/*&clAmdBlasCtrmmEx_definition*/, - NULL/*&clAmdBlasCtrmv_definition*/, - NULL/*&clAmdBlasCtrsm_definition*/, - NULL/*&clAmdBlasCtrsmEx_definition*/, - NULL/*&clAmdBlasCtrsv_definition*/, - NULL/*&clAmdBlasDasum_definition*/, - NULL/*&clAmdBlasDaxpy_definition*/, - NULL/*&clAmdBlasDcopy_definition*/, - NULL/*&clAmdBlasDdot_definition*/, - NULL/*&clAmdBlasDgbmv_definition*/, - NULL/*&clAmdBlasDgemm_definition*/, - &clAmdBlasDgemmEx_definition, - NULL/*&clAmdBlasDgemv_definition*/, - NULL/*&clAmdBlasDgemvEx_definition*/, - NULL/*&clAmdBlasDger_definition*/, - NULL/*&clAmdBlasDnrm2_definition*/, - NULL/*&clAmdBlasDrot_definition*/, - NULL/*&clAmdBlasDrotg_definition*/, - NULL/*&clAmdBlasDrotm_definition*/, - NULL/*&clAmdBlasDrotmg_definition*/, - NULL/*&clAmdBlasDsbmv_definition*/, - NULL/*&clAmdBlasDscal_definition*/, - NULL/*&clAmdBlasDspmv_definition*/, - NULL/*&clAmdBlasDspr_definition*/, - NULL/*&clAmdBlasDspr2_definition*/, - NULL/*&clAmdBlasDswap_definition*/, - NULL/*&clAmdBlasDsymm_definition*/, - NULL/*&clAmdBlasDsymv_definition*/, - NULL/*&clAmdBlasDsymvEx_definition*/, - NULL/*&clAmdBlasDsyr_definition*/, - NULL/*&clAmdBlasDsyr2_definition*/, - NULL/*&clAmdBlasDsyr2k_definition*/, - NULL/*&clAmdBlasDsyr2kEx_definition*/, - NULL/*&clAmdBlasDsyrk_definition*/, - NULL/*&clAmdBlasDsyrkEx_definition*/, - NULL/*&clAmdBlasDtbmv_definition*/, - NULL/*&clAmdBlasDtbsv_definition*/, - NULL/*&clAmdBlasDtpmv_definition*/, - NULL/*&clAmdBlasDtpsv_definition*/, - NULL/*&clAmdBlasDtrmm_definition*/, - NULL/*&clAmdBlasDtrmmEx_definition*/, - NULL/*&clAmdBlasDtrmv_definition*/, - NULL/*&clAmdBlasDtrsm_definition*/, - NULL/*&clAmdBlasDtrsmEx_definition*/, - NULL/*&clAmdBlasDtrsv_definition*/, - NULL/*&clAmdBlasDzasum_definition*/, - NULL/*&clAmdBlasDznrm2_definition*/, - NULL/*&clAmdBlasGetVersion_definition*/, - NULL/*&clAmdBlasRemoveScratchImage_definition*/, - NULL/*&clAmdBlasSasum_definition*/, - NULL/*&clAmdBlasSaxpy_definition*/, - NULL/*&clAmdBlasScasum_definition*/, - NULL/*&clAmdBlasScnrm2_definition*/, - NULL/*&clAmdBlasScopy_definition*/, - NULL/*&clAmdBlasSdot_definition*/, - &clAmdBlasSetup_definition, - NULL/*&clAmdBlasSgbmv_definition*/, - NULL/*&clAmdBlasSgemm_definition*/, - &clAmdBlasSgemmEx_definition, - NULL/*&clAmdBlasSgemv_definition*/, - NULL/*&clAmdBlasSgemvEx_definition*/, - NULL/*&clAmdBlasSger_definition*/, - NULL/*&clAmdBlasSnrm2_definition*/, - NULL/*&clAmdBlasSrot_definition*/, - NULL/*&clAmdBlasSrotg_definition*/, - NULL/*&clAmdBlasSrotm_definition*/, - NULL/*&clAmdBlasSrotmg_definition*/, - NULL/*&clAmdBlasSsbmv_definition*/, - NULL/*&clAmdBlasSscal_definition*/, - NULL/*&clAmdBlasSspmv_definition*/, - NULL/*&clAmdBlasSspr_definition*/, - NULL/*&clAmdBlasSspr2_definition*/, - NULL/*&clAmdBlasSswap_definition*/, - NULL/*&clAmdBlasSsymm_definition*/, - NULL/*&clAmdBlasSsymv_definition*/, - NULL/*&clAmdBlasSsymvEx_definition*/, - NULL/*&clAmdBlasSsyr_definition*/, - NULL/*&clAmdBlasSsyr2_definition*/, - NULL/*&clAmdBlasSsyr2k_definition*/, - NULL/*&clAmdBlasSsyr2kEx_definition*/, - NULL/*&clAmdBlasSsyrk_definition*/, - NULL/*&clAmdBlasSsyrkEx_definition*/, - NULL/*&clAmdBlasStbmv_definition*/, - NULL/*&clAmdBlasStbsv_definition*/, - NULL/*&clAmdBlasStpmv_definition*/, - NULL/*&clAmdBlasStpsv_definition*/, - NULL/*&clAmdBlasStrmm_definition*/, - NULL/*&clAmdBlasStrmmEx_definition*/, - NULL/*&clAmdBlasStrmv_definition*/, - NULL/*&clAmdBlasStrsm_definition*/, - NULL/*&clAmdBlasStrsmEx_definition*/, - NULL/*&clAmdBlasStrsv_definition*/, - &clAmdBlasTeardown_definition, - NULL/*&clAmdBlasZaxpy_definition*/, - NULL/*&clAmdBlasZcopy_definition*/, - NULL/*&clAmdBlasZdotc_definition*/, - NULL/*&clAmdBlasZdotu_definition*/, - NULL/*&clAmdBlasZdrot_definition*/, - NULL/*&clAmdBlasZdscal_definition*/, - NULL/*&clAmdBlasZgbmv_definition*/, - NULL/*&clAmdBlasZgemm_definition*/, - &clAmdBlasZgemmEx_definition, - NULL/*&clAmdBlasZgemv_definition*/, - NULL/*&clAmdBlasZgemvEx_definition*/, - NULL/*&clAmdBlasZgerc_definition*/, - NULL/*&clAmdBlasZgeru_definition*/, - NULL/*&clAmdBlasZhbmv_definition*/, - NULL/*&clAmdBlasZhemm_definition*/, - NULL/*&clAmdBlasZhemv_definition*/, - NULL/*&clAmdBlasZher_definition*/, - NULL/*&clAmdBlasZher2_definition*/, - NULL/*&clAmdBlasZher2k_definition*/, - NULL/*&clAmdBlasZherk_definition*/, - NULL/*&clAmdBlasZhpmv_definition*/, - NULL/*&clAmdBlasZhpr_definition*/, - NULL/*&clAmdBlasZhpr2_definition*/, - NULL/*&clAmdBlasZrotg_definition*/, - NULL/*&clAmdBlasZscal_definition*/, - NULL/*&clAmdBlasZswap_definition*/, - NULL/*&clAmdBlasZsymm_definition*/, - NULL/*&clAmdBlasZsyr2k_definition*/, - NULL/*&clAmdBlasZsyr2kEx_definition*/, - NULL/*&clAmdBlasZsyrk_definition*/, - NULL/*&clAmdBlasZsyrkEx_definition*/, - NULL/*&clAmdBlasZtbmv_definition*/, - NULL/*&clAmdBlasZtbsv_definition*/, - NULL/*&clAmdBlasZtpmv_definition*/, - NULL/*&clAmdBlasZtpsv_definition*/, - NULL/*&clAmdBlasZtrmm_definition*/, - NULL/*&clAmdBlasZtrmmEx_definition*/, - NULL/*&clAmdBlasZtrmv_definition*/, - NULL/*&clAmdBlasZtrsm_definition*/, - NULL/*&clAmdBlasZtrsmEx_definition*/, - NULL/*&clAmdBlasZtrsv_definition*/, - NULL/*&clAmdBlasiCamax_definition*/, - NULL/*&clAmdBlasiDamax_definition*/, - NULL/*&clAmdBlasiSamax_definition*/, - NULL/*&clAmdBlasiZamax_definition*/, -}; - -// number of enabled functions: 6 diff --git a/modules/core/src/opencl/runtime/autogenerated/opencl_clamdfft_impl.hpp b/modules/core/src/opencl/runtime/autogenerated/opencl_clamdfft_impl.hpp deleted file mode 100644 index 66532101c61b..000000000000 --- a/modules/core/src/opencl/runtime/autogenerated/opencl_clamdfft_impl.hpp +++ /dev/null @@ -1,357 +0,0 @@ -// -// AUTOGENERATED, DO NOT EDIT -// -// generated by parser_clamdfft.py -enum OPENCLAMDFFT_FN_ID { - OPENCLAMDFFT_FN_clAmdFftBakePlan = 0, -// OPENCLAMDFFT_FN_clAmdFftCopyPlan = 1, - OPENCLAMDFFT_FN_clAmdFftCreateDefaultPlan = 2, - OPENCLAMDFFT_FN_clAmdFftDestroyPlan = 3, - OPENCLAMDFFT_FN_clAmdFftEnqueueTransform = 4, -// OPENCLAMDFFT_FN_clAmdFftGetLayout = 5, -// OPENCLAMDFFT_FN_clAmdFftGetPlanBatchSize = 6, -// OPENCLAMDFFT_FN_clAmdFftGetPlanContext = 7, -// OPENCLAMDFFT_FN_clAmdFftGetPlanDim = 8, -// OPENCLAMDFFT_FN_clAmdFftGetPlanDistance = 9, -// OPENCLAMDFFT_FN_clAmdFftGetPlanInStride = 10, -// OPENCLAMDFFT_FN_clAmdFftGetPlanLength = 11, -// OPENCLAMDFFT_FN_clAmdFftGetPlanOutStride = 12, -// OPENCLAMDFFT_FN_clAmdFftGetPlanPrecision = 13, -// OPENCLAMDFFT_FN_clAmdFftGetPlanScale = 14, -// OPENCLAMDFFT_FN_clAmdFftGetPlanTransposeResult = 15, -// OPENCLAMDFFT_FN_clAmdFftGetResultLocation = 16, - OPENCLAMDFFT_FN_clAmdFftGetTmpBufSize = 17, - OPENCLAMDFFT_FN_clAmdFftGetVersion = 18, - OPENCLAMDFFT_FN_clAmdFftSetLayout = 19, - OPENCLAMDFFT_FN_clAmdFftSetPlanBatchSize = 20, -// OPENCLAMDFFT_FN_clAmdFftSetPlanDim = 21, - OPENCLAMDFFT_FN_clAmdFftSetPlanDistance = 22, - OPENCLAMDFFT_FN_clAmdFftSetPlanInStride = 23, -// OPENCLAMDFFT_FN_clAmdFftSetPlanLength = 24, - OPENCLAMDFFT_FN_clAmdFftSetPlanOutStride = 25, - OPENCLAMDFFT_FN_clAmdFftSetPlanPrecision = 26, - OPENCLAMDFFT_FN_clAmdFftSetPlanScale = 27, -// OPENCLAMDFFT_FN_clAmdFftSetPlanTransposeResult = 28, - OPENCLAMDFFT_FN_clAmdFftSetResultLocation = 29, - OPENCLAMDFFT_FN_clAmdFftSetup = 30, - OPENCLAMDFFT_FN_clAmdFftTeardown = 31, -}; - -namespace { -// generated by parser_clamdfft.py -#define openclamdfft_fn0(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(); } \ - -#define openclamdfft_fn1(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1); } \ - -#define openclamdfft_fn2(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2); } \ - -#define openclamdfft_fn3(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3); } \ - -#define openclamdfft_fn4(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4); } \ - -#define openclamdfft_fn5(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5); } \ - -#define openclamdfft_fn6(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6); } \ - -#define openclamdfft_fn7(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7); } \ - -#define openclamdfft_fn8(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8); } \ - -#define openclamdfft_fn9(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } \ - -#define openclamdfft_fn10(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } \ - -#define openclamdfft_fn11(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } \ - -#define openclamdfft_fn12(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } \ - -#define openclamdfft_fn13(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } \ - -#define openclamdfft_fn14(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } \ - -#define openclamdfft_fn15(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } \ - -#define openclamdfft_fn16(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } \ - -#define openclamdfft_fn17(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17); } \ - -#define openclamdfft_fn18(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18); } \ - -#define openclamdfft_fn19(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19); } \ - -#define openclamdfft_fn20(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); } \ - -#define openclamdfft_fn21(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21); } \ - -#define openclamdfft_fn22(ID, _R, decl_args) \ - typedef _R (*ID##FN)decl_args; \ - static _R ID##_switch_fn decl_args \ - { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22); } \ - -} - -// generated by parser_clamdfft.py -openclamdfft_fn5(OPENCLAMDFFT_FN_clAmdFftBakePlan, clAmdFftStatus, (clAmdFftPlanHandle p1, cl_uint p2, cl_command_queue* p3, void (CL_CALLBACK*p4) (clAmdFftPlanHandle plHandle, void* user_data), void* p5)) -clAmdFftStatus (*clAmdFftBakePlan)(clAmdFftPlanHandle, cl_uint, cl_command_queue*, void (CL_CALLBACK*) (clAmdFftPlanHandle plHandle, void* user_data), void*) = - OPENCLAMDFFT_FN_clAmdFftBakePlan_switch_fn; -static const struct DynamicFnEntry clAmdFftBakePlan_definition = { "clAmdFftBakePlan", (void**)&clAmdFftBakePlan}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftCopyPlan, clAmdFftStatus, (clAmdFftPlanHandle* p1, cl_context p2, clAmdFftPlanHandle p3)) -//clAmdFftStatus (*clAmdFftCopyPlan)(clAmdFftPlanHandle*, cl_context, clAmdFftPlanHandle) = -// OPENCLAMDFFT_FN_clAmdFftCopyPlan_switch_fn; -//static const struct DynamicFnEntry clAmdFftCopyPlan_definition = { "clAmdFftCopyPlan", (void**)&clAmdFftCopyPlan}; - -openclamdfft_fn4(OPENCLAMDFFT_FN_clAmdFftCreateDefaultPlan, clAmdFftStatus, (clAmdFftPlanHandle* p1, cl_context p2, const clAmdFftDim p3, const size_t* p4)) -clAmdFftStatus (*clAmdFftCreateDefaultPlan)(clAmdFftPlanHandle*, cl_context, const clAmdFftDim, const size_t*) = - OPENCLAMDFFT_FN_clAmdFftCreateDefaultPlan_switch_fn; -static const struct DynamicFnEntry clAmdFftCreateDefaultPlan_definition = { "clAmdFftCreateDefaultPlan", (void**)&clAmdFftCreateDefaultPlan}; - -openclamdfft_fn1(OPENCLAMDFFT_FN_clAmdFftDestroyPlan, clAmdFftStatus, (clAmdFftPlanHandle* p1)) -clAmdFftStatus (*clAmdFftDestroyPlan)(clAmdFftPlanHandle*) = - OPENCLAMDFFT_FN_clAmdFftDestroyPlan_switch_fn; -static const struct DynamicFnEntry clAmdFftDestroyPlan_definition = { "clAmdFftDestroyPlan", (void**)&clAmdFftDestroyPlan}; - -openclamdfft_fn10(OPENCLAMDFFT_FN_clAmdFftEnqueueTransform, clAmdFftStatus, (clAmdFftPlanHandle p1, clAmdFftDirection p2, cl_uint p3, cl_command_queue* p4, cl_uint p5, const cl_event* p6, cl_event* p7, cl_mem* p8, cl_mem* p9, cl_mem p10)) -clAmdFftStatus (*clAmdFftEnqueueTransform)(clAmdFftPlanHandle, clAmdFftDirection, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*, cl_mem*, cl_mem*, cl_mem) = - OPENCLAMDFFT_FN_clAmdFftEnqueueTransform_switch_fn; -static const struct DynamicFnEntry clAmdFftEnqueueTransform_definition = { "clAmdFftEnqueueTransform", (void**)&clAmdFftEnqueueTransform}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetLayout, clAmdFftStatus, (const clAmdFftPlanHandle p1, clAmdFftLayout* p2, clAmdFftLayout* p3)) -//clAmdFftStatus (*clAmdFftGetLayout)(const clAmdFftPlanHandle, clAmdFftLayout*, clAmdFftLayout*) = -// OPENCLAMDFFT_FN_clAmdFftGetLayout_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetLayout_definition = { "clAmdFftGetLayout", (void**)&clAmdFftGetLayout}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftGetPlanBatchSize, clAmdFftStatus, (const clAmdFftPlanHandle p1, size_t* p2)) -//clAmdFftStatus (*clAmdFftGetPlanBatchSize)(const clAmdFftPlanHandle, size_t*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanBatchSize_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanBatchSize_definition = { "clAmdFftGetPlanBatchSize", (void**)&clAmdFftGetPlanBatchSize}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftGetPlanContext, clAmdFftStatus, (const clAmdFftPlanHandle p1, cl_context* p2)) -//clAmdFftStatus (*clAmdFftGetPlanContext)(const clAmdFftPlanHandle, cl_context*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanContext_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanContext_definition = { "clAmdFftGetPlanContext", (void**)&clAmdFftGetPlanContext}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetPlanDim, clAmdFftStatus, (const clAmdFftPlanHandle p1, clAmdFftDim* p2, cl_uint* p3)) -//clAmdFftStatus (*clAmdFftGetPlanDim)(const clAmdFftPlanHandle, clAmdFftDim*, cl_uint*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanDim_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanDim_definition = { "clAmdFftGetPlanDim", (void**)&clAmdFftGetPlanDim}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetPlanDistance, clAmdFftStatus, (const clAmdFftPlanHandle p1, size_t* p2, size_t* p3)) -//clAmdFftStatus (*clAmdFftGetPlanDistance)(const clAmdFftPlanHandle, size_t*, size_t*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanDistance_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanDistance_definition = { "clAmdFftGetPlanDistance", (void**)&clAmdFftGetPlanDistance}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetPlanInStride, clAmdFftStatus, (const clAmdFftPlanHandle p1, const clAmdFftDim p2, size_t* p3)) -//clAmdFftStatus (*clAmdFftGetPlanInStride)(const clAmdFftPlanHandle, const clAmdFftDim, size_t*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanInStride_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanInStride_definition = { "clAmdFftGetPlanInStride", (void**)&clAmdFftGetPlanInStride}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetPlanLength, clAmdFftStatus, (const clAmdFftPlanHandle p1, const clAmdFftDim p2, size_t* p3)) -//clAmdFftStatus (*clAmdFftGetPlanLength)(const clAmdFftPlanHandle, const clAmdFftDim, size_t*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanLength_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanLength_definition = { "clAmdFftGetPlanLength", (void**)&clAmdFftGetPlanLength}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetPlanOutStride, clAmdFftStatus, (const clAmdFftPlanHandle p1, const clAmdFftDim p2, size_t* p3)) -//clAmdFftStatus (*clAmdFftGetPlanOutStride)(const clAmdFftPlanHandle, const clAmdFftDim, size_t*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanOutStride_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanOutStride_definition = { "clAmdFftGetPlanOutStride", (void**)&clAmdFftGetPlanOutStride}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftGetPlanPrecision, clAmdFftStatus, (const clAmdFftPlanHandle p1, clAmdFftPrecision* p2)) -//clAmdFftStatus (*clAmdFftGetPlanPrecision)(const clAmdFftPlanHandle, clAmdFftPrecision*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanPrecision_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanPrecision_definition = { "clAmdFftGetPlanPrecision", (void**)&clAmdFftGetPlanPrecision}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetPlanScale, clAmdFftStatus, (const clAmdFftPlanHandle p1, clAmdFftDirection p2, cl_float* p3)) -//clAmdFftStatus (*clAmdFftGetPlanScale)(const clAmdFftPlanHandle, clAmdFftDirection, cl_float*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanScale_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanScale_definition = { "clAmdFftGetPlanScale", (void**)&clAmdFftGetPlanScale}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftGetPlanTransposeResult, clAmdFftStatus, (const clAmdFftPlanHandle p1, clAmdFftResultTransposed* p2)) -//clAmdFftStatus (*clAmdFftGetPlanTransposeResult)(const clAmdFftPlanHandle, clAmdFftResultTransposed*) = -// OPENCLAMDFFT_FN_clAmdFftGetPlanTransposeResult_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetPlanTransposeResult_definition = { "clAmdFftGetPlanTransposeResult", (void**)&clAmdFftGetPlanTransposeResult}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftGetResultLocation, clAmdFftStatus, (const clAmdFftPlanHandle p1, clAmdFftResultLocation* p2)) -//clAmdFftStatus (*clAmdFftGetResultLocation)(const clAmdFftPlanHandle, clAmdFftResultLocation*) = -// OPENCLAMDFFT_FN_clAmdFftGetResultLocation_switch_fn; -//static const struct DynamicFnEntry clAmdFftGetResultLocation_definition = { "clAmdFftGetResultLocation", (void**)&clAmdFftGetResultLocation}; - -openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftGetTmpBufSize, clAmdFftStatus, (const clAmdFftPlanHandle p1, size_t* p2)) -clAmdFftStatus (*clAmdFftGetTmpBufSize)(const clAmdFftPlanHandle, size_t*) = - OPENCLAMDFFT_FN_clAmdFftGetTmpBufSize_switch_fn; -static const struct DynamicFnEntry clAmdFftGetTmpBufSize_definition = { "clAmdFftGetTmpBufSize", (void**)&clAmdFftGetTmpBufSize}; - -openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftGetVersion, clAmdFftStatus, (cl_uint* p1, cl_uint* p2, cl_uint* p3)) -clAmdFftStatus (*clAmdFftGetVersion)(cl_uint*, cl_uint*, cl_uint*) = - OPENCLAMDFFT_FN_clAmdFftGetVersion_switch_fn; -static const struct DynamicFnEntry clAmdFftGetVersion_definition = { "clAmdFftGetVersion", (void**)&clAmdFftGetVersion}; - -openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftSetLayout, clAmdFftStatus, (clAmdFftPlanHandle p1, clAmdFftLayout p2, clAmdFftLayout p3)) -clAmdFftStatus (*clAmdFftSetLayout)(clAmdFftPlanHandle, clAmdFftLayout, clAmdFftLayout) = - OPENCLAMDFFT_FN_clAmdFftSetLayout_switch_fn; -static const struct DynamicFnEntry clAmdFftSetLayout_definition = { "clAmdFftSetLayout", (void**)&clAmdFftSetLayout}; - -openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftSetPlanBatchSize, clAmdFftStatus, (clAmdFftPlanHandle p1, size_t p2)) -clAmdFftStatus (*clAmdFftSetPlanBatchSize)(clAmdFftPlanHandle, size_t) = - OPENCLAMDFFT_FN_clAmdFftSetPlanBatchSize_switch_fn; -static const struct DynamicFnEntry clAmdFftSetPlanBatchSize_definition = { "clAmdFftSetPlanBatchSize", (void**)&clAmdFftSetPlanBatchSize}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftSetPlanDim, clAmdFftStatus, (clAmdFftPlanHandle p1, const clAmdFftDim p2)) -//clAmdFftStatus (*clAmdFftSetPlanDim)(clAmdFftPlanHandle, const clAmdFftDim) = -// OPENCLAMDFFT_FN_clAmdFftSetPlanDim_switch_fn; -//static const struct DynamicFnEntry clAmdFftSetPlanDim_definition = { "clAmdFftSetPlanDim", (void**)&clAmdFftSetPlanDim}; - -openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftSetPlanDistance, clAmdFftStatus, (clAmdFftPlanHandle p1, size_t p2, size_t p3)) -clAmdFftStatus (*clAmdFftSetPlanDistance)(clAmdFftPlanHandle, size_t, size_t) = - OPENCLAMDFFT_FN_clAmdFftSetPlanDistance_switch_fn; -static const struct DynamicFnEntry clAmdFftSetPlanDistance_definition = { "clAmdFftSetPlanDistance", (void**)&clAmdFftSetPlanDistance}; - -openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftSetPlanInStride, clAmdFftStatus, (clAmdFftPlanHandle p1, const clAmdFftDim p2, size_t* p3)) -clAmdFftStatus (*clAmdFftSetPlanInStride)(clAmdFftPlanHandle, const clAmdFftDim, size_t*) = - OPENCLAMDFFT_FN_clAmdFftSetPlanInStride_switch_fn; -static const struct DynamicFnEntry clAmdFftSetPlanInStride_definition = { "clAmdFftSetPlanInStride", (void**)&clAmdFftSetPlanInStride}; - -//openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftSetPlanLength, clAmdFftStatus, (clAmdFftPlanHandle p1, const clAmdFftDim p2, const size_t* p3)) -//clAmdFftStatus (*clAmdFftSetPlanLength)(clAmdFftPlanHandle, const clAmdFftDim, const size_t*) = -// OPENCLAMDFFT_FN_clAmdFftSetPlanLength_switch_fn; -//static const struct DynamicFnEntry clAmdFftSetPlanLength_definition = { "clAmdFftSetPlanLength", (void**)&clAmdFftSetPlanLength}; - -openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftSetPlanOutStride, clAmdFftStatus, (clAmdFftPlanHandle p1, const clAmdFftDim p2, size_t* p3)) -clAmdFftStatus (*clAmdFftSetPlanOutStride)(clAmdFftPlanHandle, const clAmdFftDim, size_t*) = - OPENCLAMDFFT_FN_clAmdFftSetPlanOutStride_switch_fn; -static const struct DynamicFnEntry clAmdFftSetPlanOutStride_definition = { "clAmdFftSetPlanOutStride", (void**)&clAmdFftSetPlanOutStride}; - -openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftSetPlanPrecision, clAmdFftStatus, (clAmdFftPlanHandle p1, clAmdFftPrecision p2)) -clAmdFftStatus (*clAmdFftSetPlanPrecision)(clAmdFftPlanHandle, clAmdFftPrecision) = - OPENCLAMDFFT_FN_clAmdFftSetPlanPrecision_switch_fn; -static const struct DynamicFnEntry clAmdFftSetPlanPrecision_definition = { "clAmdFftSetPlanPrecision", (void**)&clAmdFftSetPlanPrecision}; - -openclamdfft_fn3(OPENCLAMDFFT_FN_clAmdFftSetPlanScale, clAmdFftStatus, (clAmdFftPlanHandle p1, clAmdFftDirection p2, cl_float p3)) -clAmdFftStatus (*clAmdFftSetPlanScale)(clAmdFftPlanHandle, clAmdFftDirection, cl_float) = - OPENCLAMDFFT_FN_clAmdFftSetPlanScale_switch_fn; -static const struct DynamicFnEntry clAmdFftSetPlanScale_definition = { "clAmdFftSetPlanScale", (void**)&clAmdFftSetPlanScale}; - -//openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftSetPlanTransposeResult, clAmdFftStatus, (clAmdFftPlanHandle p1, clAmdFftResultTransposed p2)) -//clAmdFftStatus (*clAmdFftSetPlanTransposeResult)(clAmdFftPlanHandle, clAmdFftResultTransposed) = -// OPENCLAMDFFT_FN_clAmdFftSetPlanTransposeResult_switch_fn; -//static const struct DynamicFnEntry clAmdFftSetPlanTransposeResult_definition = { "clAmdFftSetPlanTransposeResult", (void**)&clAmdFftSetPlanTransposeResult}; - -openclamdfft_fn2(OPENCLAMDFFT_FN_clAmdFftSetResultLocation, clAmdFftStatus, (clAmdFftPlanHandle p1, clAmdFftResultLocation p2)) -clAmdFftStatus (*clAmdFftSetResultLocation)(clAmdFftPlanHandle, clAmdFftResultLocation) = - OPENCLAMDFFT_FN_clAmdFftSetResultLocation_switch_fn; -static const struct DynamicFnEntry clAmdFftSetResultLocation_definition = { "clAmdFftSetResultLocation", (void**)&clAmdFftSetResultLocation}; - -openclamdfft_fn1(OPENCLAMDFFT_FN_clAmdFftSetup, clAmdFftStatus, (const clAmdFftSetupData* p1)) -clAmdFftStatus (*clAmdFftSetup)(const clAmdFftSetupData*) = - OPENCLAMDFFT_FN_clAmdFftSetup_switch_fn; -static const struct DynamicFnEntry clAmdFftSetup_definition = { "clAmdFftSetup", (void**)&clAmdFftSetup}; - -openclamdfft_fn0(OPENCLAMDFFT_FN_clAmdFftTeardown, clAmdFftStatus, ()) -clAmdFftStatus (*clAmdFftTeardown)() = - OPENCLAMDFFT_FN_clAmdFftTeardown_switch_fn; -static const struct DynamicFnEntry clAmdFftTeardown_definition = { "clAmdFftTeardown", (void**)&clAmdFftTeardown}; - - -// generated by parser_clamdfft.py -static const struct DynamicFnEntry* openclamdfft_fn[] = { - &clAmdFftBakePlan_definition, - NULL/*&clAmdFftCopyPlan_definition*/, - &clAmdFftCreateDefaultPlan_definition, - &clAmdFftDestroyPlan_definition, - &clAmdFftEnqueueTransform_definition, - NULL/*&clAmdFftGetLayout_definition*/, - NULL/*&clAmdFftGetPlanBatchSize_definition*/, - NULL/*&clAmdFftGetPlanContext_definition*/, - NULL/*&clAmdFftGetPlanDim_definition*/, - NULL/*&clAmdFftGetPlanDistance_definition*/, - NULL/*&clAmdFftGetPlanInStride_definition*/, - NULL/*&clAmdFftGetPlanLength_definition*/, - NULL/*&clAmdFftGetPlanOutStride_definition*/, - NULL/*&clAmdFftGetPlanPrecision_definition*/, - NULL/*&clAmdFftGetPlanScale_definition*/, - NULL/*&clAmdFftGetPlanTransposeResult_definition*/, - NULL/*&clAmdFftGetResultLocation_definition*/, - &clAmdFftGetTmpBufSize_definition, - &clAmdFftGetVersion_definition, - &clAmdFftSetLayout_definition, - &clAmdFftSetPlanBatchSize_definition, - NULL/*&clAmdFftSetPlanDim_definition*/, - &clAmdFftSetPlanDistance_definition, - &clAmdFftSetPlanInStride_definition, - NULL/*&clAmdFftSetPlanLength_definition*/, - &clAmdFftSetPlanOutStride_definition, - &clAmdFftSetPlanPrecision_definition, - &clAmdFftSetPlanScale_definition, - NULL/*&clAmdFftSetPlanTransposeResult_definition*/, - &clAmdFftSetResultLocation_definition, - &clAmdFftSetup_definition, - &clAmdFftTeardown_definition, -}; - -// number of enabled functions: 16 diff --git a/modules/core/src/opencl/runtime/autogenerated/opencl_clblas_impl.hpp b/modules/core/src/opencl/runtime/autogenerated/opencl_clblas_impl.hpp new file mode 100644 index 000000000000..57b52fcf0747 --- /dev/null +++ b/modules/core/src/opencl/runtime/autogenerated/opencl_clblas_impl.hpp @@ -0,0 +1,1162 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +// generated by parser_clblas.py +enum OPENCLAMDBLAS_FN_ID { +// OPENCLAMDBLAS_FN_clblasCaxpy = 0, +// OPENCLAMDBLAS_FN_clblasCcopy = 1, +// OPENCLAMDBLAS_FN_clblasCdotc = 2, +// OPENCLAMDBLAS_FN_clblasCdotu = 3, +// OPENCLAMDBLAS_FN_clblasCgbmv = 4, + OPENCLAMDBLAS_FN_clblasCgemm = 5, +// OPENCLAMDBLAS_FN_clblasCgemv = 6, +// OPENCLAMDBLAS_FN_clblasCgerc = 7, +// OPENCLAMDBLAS_FN_clblasCgeru = 8, +// OPENCLAMDBLAS_FN_clblasChbmv = 9, +// OPENCLAMDBLAS_FN_clblasChemm = 10, +// OPENCLAMDBLAS_FN_clblasChemv = 11, +// OPENCLAMDBLAS_FN_clblasCher = 12, +// OPENCLAMDBLAS_FN_clblasCher2 = 13, +// OPENCLAMDBLAS_FN_clblasCher2k = 14, +// OPENCLAMDBLAS_FN_clblasCherk = 15, +// OPENCLAMDBLAS_FN_clblasChpmv = 16, +// OPENCLAMDBLAS_FN_clblasChpr = 17, +// OPENCLAMDBLAS_FN_clblasChpr2 = 18, +// OPENCLAMDBLAS_FN_clblasCrotg = 19, +// OPENCLAMDBLAS_FN_clblasCscal = 20, +// OPENCLAMDBLAS_FN_clblasCsrot = 21, +// OPENCLAMDBLAS_FN_clblasCsscal = 22, +// OPENCLAMDBLAS_FN_clblasCswap = 23, +// OPENCLAMDBLAS_FN_clblasCsymm = 24, +// OPENCLAMDBLAS_FN_clblasCsyr2k = 25, +// OPENCLAMDBLAS_FN_clblasCsyrk = 26, +// OPENCLAMDBLAS_FN_clblasCtbmv = 27, +// OPENCLAMDBLAS_FN_clblasCtbsv = 28, +// OPENCLAMDBLAS_FN_clblasCtpmv = 29, +// OPENCLAMDBLAS_FN_clblasCtpsv = 30, +// OPENCLAMDBLAS_FN_clblasCtrmm = 31, +// OPENCLAMDBLAS_FN_clblasCtrmv = 32, +// OPENCLAMDBLAS_FN_clblasCtrsm = 33, +// OPENCLAMDBLAS_FN_clblasCtrsv = 34, +// OPENCLAMDBLAS_FN_clblasDasum = 35, +// OPENCLAMDBLAS_FN_clblasDaxpy = 36, +// OPENCLAMDBLAS_FN_clblasDcopy = 37, +// OPENCLAMDBLAS_FN_clblasDdot = 38, +// OPENCLAMDBLAS_FN_clblasDgbmv = 39, + OPENCLAMDBLAS_FN_clblasDgemm = 40, +// OPENCLAMDBLAS_FN_clblasDgemv = 41, +// OPENCLAMDBLAS_FN_clblasDger = 42, +// OPENCLAMDBLAS_FN_clblasDnrm2 = 43, +// OPENCLAMDBLAS_FN_clblasDrot = 44, +// OPENCLAMDBLAS_FN_clblasDrotg = 45, +// OPENCLAMDBLAS_FN_clblasDrotm = 46, +// OPENCLAMDBLAS_FN_clblasDrotmg = 47, +// OPENCLAMDBLAS_FN_clblasDsbmv = 48, +// OPENCLAMDBLAS_FN_clblasDscal = 49, +// OPENCLAMDBLAS_FN_clblasDspmv = 50, +// OPENCLAMDBLAS_FN_clblasDspr = 51, +// OPENCLAMDBLAS_FN_clblasDspr2 = 52, +// OPENCLAMDBLAS_FN_clblasDswap = 53, +// OPENCLAMDBLAS_FN_clblasDsymm = 54, +// OPENCLAMDBLAS_FN_clblasDsymv = 55, +// OPENCLAMDBLAS_FN_clblasDsyr = 56, +// OPENCLAMDBLAS_FN_clblasDsyr2 = 57, +// OPENCLAMDBLAS_FN_clblasDsyr2k = 58, +// OPENCLAMDBLAS_FN_clblasDsyrk = 59, +// OPENCLAMDBLAS_FN_clblasDtbmv = 60, +// OPENCLAMDBLAS_FN_clblasDtbsv = 61, +// OPENCLAMDBLAS_FN_clblasDtpmv = 62, +// OPENCLAMDBLAS_FN_clblasDtpsv = 63, +// OPENCLAMDBLAS_FN_clblasDtrmm = 64, +// OPENCLAMDBLAS_FN_clblasDtrmv = 65, +// OPENCLAMDBLAS_FN_clblasDtrsm = 66, +// OPENCLAMDBLAS_FN_clblasDtrsv = 67, +// OPENCLAMDBLAS_FN_clblasDzasum = 68, +// OPENCLAMDBLAS_FN_clblasDznrm2 = 69, +// OPENCLAMDBLAS_FN_clblasGetVersion = 70, +// OPENCLAMDBLAS_FN_clblasSasum = 71, +// OPENCLAMDBLAS_FN_clblasSaxpy = 72, +// OPENCLAMDBLAS_FN_clblasScasum = 73, +// OPENCLAMDBLAS_FN_clblasScnrm2 = 74, +// OPENCLAMDBLAS_FN_clblasScopy = 75, +// OPENCLAMDBLAS_FN_clblasSdot = 76, + OPENCLAMDBLAS_FN_clblasSetup = 77, +// OPENCLAMDBLAS_FN_clblasSgbmv = 78, + OPENCLAMDBLAS_FN_clblasSgemm = 79, +// OPENCLAMDBLAS_FN_clblasSgemv = 80, +// OPENCLAMDBLAS_FN_clblasSger = 81, +// OPENCLAMDBLAS_FN_clblasSnrm2 = 82, +// OPENCLAMDBLAS_FN_clblasSrot = 83, +// OPENCLAMDBLAS_FN_clblasSrotg = 84, +// OPENCLAMDBLAS_FN_clblasSrotm = 85, +// OPENCLAMDBLAS_FN_clblasSrotmg = 86, +// OPENCLAMDBLAS_FN_clblasSsbmv = 87, +// OPENCLAMDBLAS_FN_clblasSscal = 88, +// OPENCLAMDBLAS_FN_clblasSspmv = 89, +// OPENCLAMDBLAS_FN_clblasSspr = 90, +// OPENCLAMDBLAS_FN_clblasSspr2 = 91, +// OPENCLAMDBLAS_FN_clblasSswap = 92, +// OPENCLAMDBLAS_FN_clblasSsymm = 93, +// OPENCLAMDBLAS_FN_clblasSsymv = 94, +// OPENCLAMDBLAS_FN_clblasSsyr = 95, +// OPENCLAMDBLAS_FN_clblasSsyr2 = 96, +// OPENCLAMDBLAS_FN_clblasSsyr2k = 97, +// OPENCLAMDBLAS_FN_clblasSsyrk = 98, +// OPENCLAMDBLAS_FN_clblasStbmv = 99, +// OPENCLAMDBLAS_FN_clblasStbsv = 100, +// OPENCLAMDBLAS_FN_clblasStpmv = 101, +// OPENCLAMDBLAS_FN_clblasStpsv = 102, +// OPENCLAMDBLAS_FN_clblasStrmm = 103, +// OPENCLAMDBLAS_FN_clblasStrmv = 104, +// OPENCLAMDBLAS_FN_clblasStrsm = 105, +// OPENCLAMDBLAS_FN_clblasStrsv = 106, + OPENCLAMDBLAS_FN_clblasTeardown = 107, +// OPENCLAMDBLAS_FN_clblasZaxpy = 108, +// OPENCLAMDBLAS_FN_clblasZcopy = 109, +// OPENCLAMDBLAS_FN_clblasZdotc = 110, +// OPENCLAMDBLAS_FN_clblasZdotu = 111, +// OPENCLAMDBLAS_FN_clblasZdrot = 112, +// OPENCLAMDBLAS_FN_clblasZdscal = 113, +// OPENCLAMDBLAS_FN_clblasZgbmv = 114, + OPENCLAMDBLAS_FN_clblasZgemm = 115, +// OPENCLAMDBLAS_FN_clblasZgemv = 116, +// OPENCLAMDBLAS_FN_clblasZgerc = 117, +// OPENCLAMDBLAS_FN_clblasZgeru = 118, +// OPENCLAMDBLAS_FN_clblasZhbmv = 119, +// OPENCLAMDBLAS_FN_clblasZhemm = 120, +// OPENCLAMDBLAS_FN_clblasZhemv = 121, +// OPENCLAMDBLAS_FN_clblasZher = 122, +// OPENCLAMDBLAS_FN_clblasZher2 = 123, +// OPENCLAMDBLAS_FN_clblasZher2k = 124, +// OPENCLAMDBLAS_FN_clblasZherk = 125, +// OPENCLAMDBLAS_FN_clblasZhpmv = 126, +// OPENCLAMDBLAS_FN_clblasZhpr = 127, +// OPENCLAMDBLAS_FN_clblasZhpr2 = 128, +// OPENCLAMDBLAS_FN_clblasZrotg = 129, +// OPENCLAMDBLAS_FN_clblasZscal = 130, +// OPENCLAMDBLAS_FN_clblasZswap = 131, +// OPENCLAMDBLAS_FN_clblasZsymm = 132, +// OPENCLAMDBLAS_FN_clblasZsyr2k = 133, +// OPENCLAMDBLAS_FN_clblasZsyrk = 134, +// OPENCLAMDBLAS_FN_clblasZtbmv = 135, +// OPENCLAMDBLAS_FN_clblasZtbsv = 136, +// OPENCLAMDBLAS_FN_clblasZtpmv = 137, +// OPENCLAMDBLAS_FN_clblasZtpsv = 138, +// OPENCLAMDBLAS_FN_clblasZtrmm = 139, +// OPENCLAMDBLAS_FN_clblasZtrmv = 140, +// OPENCLAMDBLAS_FN_clblasZtrsm = 141, +// OPENCLAMDBLAS_FN_clblasZtrsv = 142, +// OPENCLAMDBLAS_FN_clblasiCamax = 143, +// OPENCLAMDBLAS_FN_clblasiDamax = 144, +// OPENCLAMDBLAS_FN_clblasiSamax = 145, +// OPENCLAMDBLAS_FN_clblasiZamax = 146, +}; + +namespace { +// generated by parser_clblas.py +#define openclamdblas_fn0(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(); } \ + +#define openclamdblas_fn1(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1); } \ + +#define openclamdblas_fn2(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2); } \ + +#define openclamdblas_fn3(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3); } \ + +#define openclamdblas_fn4(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4); } \ + +#define openclamdblas_fn5(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5); } \ + +#define openclamdblas_fn6(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6); } \ + +#define openclamdblas_fn7(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7); } \ + +#define openclamdblas_fn8(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8); } \ + +#define openclamdblas_fn9(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } \ + +#define openclamdblas_fn10(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } \ + +#define openclamdblas_fn11(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } \ + +#define openclamdblas_fn12(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } \ + +#define openclamdblas_fn13(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } \ + +#define openclamdblas_fn14(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } \ + +#define openclamdblas_fn15(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } \ + +#define openclamdblas_fn16(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } \ + +#define openclamdblas_fn17(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17); } \ + +#define openclamdblas_fn18(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18); } \ + +#define openclamdblas_fn19(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19); } \ + +#define openclamdblas_fn20(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); } \ + +#define openclamdblas_fn21(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21); } \ + +#define openclamdblas_fn22(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdblas_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22); } \ + +} + +// generated by parser_clblas.py +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasCaxpy, clblasStatus, (size_t p1, cl_float2 p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasCaxpy)(size_t, cl_float2, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCaxpy_switch_fn; +//static const struct DynamicFnEntry clblasCaxpy_definition = { "clblasCaxpy", (void**)&clblasCaxpy}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasCcopy, clblasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasCcopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCcopy_switch_fn; +//static const struct DynamicFnEntry clblasCcopy_definition = { "clblasCcopy", (void**)&clblasCcopy}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasCdotc, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasCdotc)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCdotc_switch_fn; +//static const struct DynamicFnEntry clblasCdotc_definition = { "clblasCdotc", (void**)&clblasCdotc}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasCdotu, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasCdotu)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCdotu_switch_fn; +//static const struct DynamicFnEntry clblasCdotu_definition = { "clblasCdotu", (void**)&clblasCdotu}; + +//openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasCgbmv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_float2 p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_float2 p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +//clblasStatus (*clblasCgbmv)(clblasOrder, clblasTranspose, size_t, size_t, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCgbmv_switch_fn; +//static const struct DynamicFnEntry clblasCgbmv_definition = { "clblasCgbmv", (void**)&clblasCgbmv}; + +openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasCgemm, clblasStatus, (clblasOrder p1, clblasTranspose p2, clblasTranspose p3, size_t p4, size_t p5, size_t p6, FloatComplex p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, FloatComplex p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +clblasStatus (*clblasCgemm)(clblasOrder, clblasTranspose, clblasTranspose, size_t, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, FloatComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = + OPENCLAMDBLAS_FN_clblasCgemm_switch_fn; +static const struct DynamicFnEntry clblasCgemm_definition = { "clblasCgemm", (void**)&clblasCgemm}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasCgemv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, FloatComplex p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, FloatComplex p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasCgemv)(clblasOrder, clblasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, FloatComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCgemv_switch_fn; +//static const struct DynamicFnEntry clblasCgemv_definition = { "clblasCgemv", (void**)&clblasCgemv}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasCgerc, clblasStatus, (clblasOrder p1, size_t p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasCgerc)(clblasOrder, size_t, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCgerc_switch_fn; +//static const struct DynamicFnEntry clblasCgerc_definition = { "clblasCgerc", (void**)&clblasCgerc}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasCgeru, clblasStatus, (clblasOrder p1, size_t p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasCgeru)(clblasOrder, size_t, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCgeru_switch_fn; +//static const struct DynamicFnEntry clblasCgeru_definition = { "clblasCgeru", (void**)&clblasCgeru}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasChbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, size_t p4, cl_float2 p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_float2 p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasChbmv)(clblasOrder, clblasUplo, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasChbmv_switch_fn; +//static const struct DynamicFnEntry clblasChbmv_definition = { "clblasChbmv", (void**)&clblasChbmv}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasChemm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, size_t p4, size_t p5, cl_float2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasChemm)(clblasOrder, clblasSide, clblasUplo, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasChemm_switch_fn; +//static const struct DynamicFnEntry clblasChemm_definition = { "clblasChemm", (void**)&clblasChemm}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasChemv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, FloatComplex p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, FloatComplex p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasChemv)(clblasOrder, clblasUplo, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, FloatComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasChemv_switch_fn; +//static const struct DynamicFnEntry clblasChemv_definition = { "clblasChemv", (void**)&clblasChemv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasCher, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasCher)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCher_switch_fn; +//static const struct DynamicFnEntry clblasCher_definition = { "clblasCher", (void**)&clblasCher}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasCher2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasCher2)(clblasOrder, clblasUplo, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCher2_switch_fn; +//static const struct DynamicFnEntry clblasCher2_definition = { "clblasCher2", (void**)&clblasCher2}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasCher2k, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasCher2k)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCher2k_switch_fn; +//static const struct DynamicFnEntry clblasCher2k_definition = { "clblasCher2k", (void**)&clblasCher2k}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasCherk, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, float p6, const cl_mem p7, size_t p8, size_t p9, float p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasCherk)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, float, const cl_mem, size_t, size_t, float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCherk_switch_fn; +//static const struct DynamicFnEntry clblasCherk_definition = { "clblasCherk", (void**)&clblasCherk}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasChpmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_float2 p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasChpmv)(clblasOrder, clblasUplo, size_t, cl_float2, const cl_mem, size_t, const cl_mem, size_t, int, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasChpmv_switch_fn; +//static const struct DynamicFnEntry clblasChpmv_definition = { "clblasChpmv", (void**)&clblasChpmv}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasChpr, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasChpr)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasChpr_switch_fn; +//static const struct DynamicFnEntry clblasChpr_definition = { "clblasChpr", (void**)&clblasChpr}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasChpr2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasChpr2)(clblasOrder, clblasUplo, size_t, cl_float2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasChpr2_switch_fn; +//static const struct DynamicFnEntry clblasChpr2_definition = { "clblasChpr2", (void**)&clblasChpr2}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasCrotg, clblasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasCrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCrotg_switch_fn; +//static const struct DynamicFnEntry clblasCrotg_definition = { "clblasCrotg", (void**)&clblasCrotg}; + +//openclamdblas_fn10(OPENCLAMDBLAS_FN_clblasCscal, clblasStatus, (size_t p1, cl_float2 p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) +//clblasStatus (*clblasCscal)(size_t, cl_float2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCscal_switch_fn; +//static const struct DynamicFnEntry clblasCscal_definition = { "clblasCscal", (void**)&clblasCscal}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasCsrot, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_float p8, cl_float p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasCsrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_float, cl_float, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCsrot_switch_fn; +//static const struct DynamicFnEntry clblasCsrot_definition = { "clblasCsrot", (void**)&clblasCsrot}; + +//openclamdblas_fn10(OPENCLAMDBLAS_FN_clblasCsscal, clblasStatus, (size_t p1, cl_float p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) +//clblasStatus (*clblasCsscal)(size_t, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCsscal_switch_fn; +//static const struct DynamicFnEntry clblasCsscal_definition = { "clblasCsscal", (void**)&clblasCsscal}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasCswap, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasCswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCswap_switch_fn; +//static const struct DynamicFnEntry clblasCswap_definition = { "clblasCswap", (void**)&clblasCswap}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasCsymm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, size_t p4, size_t p5, cl_float2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasCsymm)(clblasOrder, clblasSide, clblasUplo, size_t, size_t, cl_float2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCsymm_switch_fn; +//static const struct DynamicFnEntry clblasCsymm_definition = { "clblasCsymm", (void**)&clblasCsymm}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasCsyr2k, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, FloatComplex p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasCsyr2k)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, FloatComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCsyr2k_switch_fn; +//static const struct DynamicFnEntry clblasCsyr2k_definition = { "clblasCsyr2k", (void**)&clblasCsyr2k}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasCsyrk, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, FloatComplex p6, const cl_mem p7, size_t p8, size_t p9, FloatComplex p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasCsyrk)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, FloatComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCsyrk_switch_fn; +//static const struct DynamicFnEntry clblasCsyrk_definition = { "clblasCsyrk", (void**)&clblasCsyrk}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasCtbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasCtbmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtbmv_switch_fn; +//static const struct DynamicFnEntry clblasCtbmv_definition = { "clblasCtbmv", (void**)&clblasCtbmv}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasCtbsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasCtbsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtbsv_switch_fn; +//static const struct DynamicFnEntry clblasCtbsv_definition = { "clblasCtbsv", (void**)&clblasCtbsv}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasCtpmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasCtpmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtpmv_switch_fn; +//static const struct DynamicFnEntry clblasCtpmv_definition = { "clblasCtpmv", (void**)&clblasCtpmv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasCtpsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasCtpsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtpsv_switch_fn; +//static const struct DynamicFnEntry clblasCtpsv_definition = { "clblasCtpsv", (void**)&clblasCtpsv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasCtrmm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, FloatComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasCtrmm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtrmm_switch_fn; +//static const struct DynamicFnEntry clblasCtrmm_definition = { "clblasCtrmm", (void**)&clblasCtrmm}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasCtrmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasCtrmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtrmv_switch_fn; +//static const struct DynamicFnEntry clblasCtrmv_definition = { "clblasCtrmv", (void**)&clblasCtrmv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasCtrsm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, FloatComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasCtrsm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, FloatComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtrsm_switch_fn; +//static const struct DynamicFnEntry clblasCtrsm_definition = { "clblasCtrsm", (void**)&clblasCtrsm}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasCtrsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasCtrsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasCtrsv_switch_fn; +//static const struct DynamicFnEntry clblasCtrsv_definition = { "clblasCtrsv", (void**)&clblasCtrsv}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasDasum, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasDasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDasum_switch_fn; +//static const struct DynamicFnEntry clblasDasum_definition = { "clblasDasum", (void**)&clblasDasum}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasDaxpy, clblasStatus, (size_t p1, cl_double p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasDaxpy)(size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDaxpy_switch_fn; +//static const struct DynamicFnEntry clblasDaxpy_definition = { "clblasDaxpy", (void**)&clblasDaxpy}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasDcopy, clblasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasDcopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDcopy_switch_fn; +//static const struct DynamicFnEntry clblasDcopy_definition = { "clblasDcopy", (void**)&clblasDcopy}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasDdot, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasDdot)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDdot_switch_fn; +//static const struct DynamicFnEntry clblasDdot_definition = { "clblasDdot", (void**)&clblasDdot}; + +//openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasDgbmv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_double p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_double p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +//clblasStatus (*clblasDgbmv)(clblasOrder, clblasTranspose, size_t, size_t, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDgbmv_switch_fn; +//static const struct DynamicFnEntry clblasDgbmv_definition = { "clblasDgbmv", (void**)&clblasDgbmv}; + +openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasDgemm, clblasStatus, (clblasOrder p1, clblasTranspose p2, clblasTranspose p3, size_t p4, size_t p5, size_t p6, cl_double p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, cl_double p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +clblasStatus (*clblasDgemm)(clblasOrder, clblasTranspose, clblasTranspose, size_t, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = + OPENCLAMDBLAS_FN_clblasDgemm_switch_fn; +static const struct DynamicFnEntry clblasDgemm_definition = { "clblasDgemm", (void**)&clblasDgemm}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasDgemv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, cl_double p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_double p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasDgemv)(clblasOrder, clblasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDgemv_switch_fn; +//static const struct DynamicFnEntry clblasDgemv_definition = { "clblasDgemv", (void**)&clblasDgemv}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasDger, clblasStatus, (clblasOrder p1, size_t p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasDger)(clblasOrder, size_t, size_t, cl_double, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDger_switch_fn; +//static const struct DynamicFnEntry clblasDger_definition = { "clblasDger", (void**)&clblasDger}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasDnrm2, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasDnrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDnrm2_switch_fn; +//static const struct DynamicFnEntry clblasDnrm2_definition = { "clblasDnrm2", (void**)&clblasDnrm2}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasDrot, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_double p8, cl_double p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasDrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_double, cl_double, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDrot_switch_fn; +//static const struct DynamicFnEntry clblasDrot_definition = { "clblasDrot", (void**)&clblasDrot}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasDrotg, clblasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasDrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDrotg_switch_fn; +//static const struct DynamicFnEntry clblasDrotg_definition = { "clblasDrotg", (void**)&clblasDrotg}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasDrotm, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasDrotm)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, const cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDrotm_switch_fn; +//static const struct DynamicFnEntry clblasDrotm_definition = { "clblasDrotm", (void**)&clblasDrotm}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasDrotmg, clblasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, const cl_mem p7, size_t p8, cl_mem p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasDrotmg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDrotmg_switch_fn; +//static const struct DynamicFnEntry clblasDrotmg_definition = { "clblasDrotmg", (void**)&clblasDrotmg}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasDsbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, size_t p4, cl_double p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_double p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasDsbmv)(clblasOrder, clblasUplo, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsbmv_switch_fn; +//static const struct DynamicFnEntry clblasDsbmv_definition = { "clblasDsbmv", (void**)&clblasDsbmv}; + +//openclamdblas_fn10(OPENCLAMDBLAS_FN_clblasDscal, clblasStatus, (size_t p1, cl_double p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) +//clblasStatus (*clblasDscal)(size_t, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDscal_switch_fn; +//static const struct DynamicFnEntry clblasDscal_definition = { "clblasDscal", (void**)&clblasDscal}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasDspmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_double p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasDspmv)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDspmv_switch_fn; +//static const struct DynamicFnEntry clblasDspmv_definition = { "clblasDspmv", (void**)&clblasDspmv}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasDspr, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasDspr)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDspr_switch_fn; +//static const struct DynamicFnEntry clblasDspr_definition = { "clblasDspr", (void**)&clblasDspr}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasDspr2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasDspr2)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDspr2_switch_fn; +//static const struct DynamicFnEntry clblasDspr2_definition = { "clblasDspr2", (void**)&clblasDspr2}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasDswap, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasDswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDswap_switch_fn; +//static const struct DynamicFnEntry clblasDswap_definition = { "clblasDswap", (void**)&clblasDswap}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasDsymm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasDsymm)(clblasOrder, clblasSide, clblasUplo, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsymm_switch_fn; +//static const struct DynamicFnEntry clblasDsymm_definition = { "clblasDsymm", (void**)&clblasDsymm}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasDsymv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, cl_double p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasDsymv)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsymv_switch_fn; +//static const struct DynamicFnEntry clblasDsymv_definition = { "clblasDsymv", (void**)&clblasDsymv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasDsyr, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasDsyr)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsyr_switch_fn; +//static const struct DynamicFnEntry clblasDsyr_definition = { "clblasDsyr", (void**)&clblasDsyr}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasDsyr2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasDsyr2)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsyr2_switch_fn; +//static const struct DynamicFnEntry clblasDsyr2_definition = { "clblasDsyr2", (void**)&clblasDsyr2}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasDsyr2k, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasDsyr2k)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsyr2k_switch_fn; +//static const struct DynamicFnEntry clblasDsyr2k_definition = { "clblasDsyr2k", (void**)&clblasDsyr2k}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasDsyrk, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, cl_double p6, const cl_mem p7, size_t p8, size_t p9, cl_double p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasDsyrk)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, cl_double, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDsyrk_switch_fn; +//static const struct DynamicFnEntry clblasDsyrk_definition = { "clblasDsyrk", (void**)&clblasDsyrk}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasDtbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasDtbmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtbmv_switch_fn; +//static const struct DynamicFnEntry clblasDtbmv_definition = { "clblasDtbmv", (void**)&clblasDtbmv}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasDtbsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasDtbsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtbsv_switch_fn; +//static const struct DynamicFnEntry clblasDtbsv_definition = { "clblasDtbsv", (void**)&clblasDtbsv}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasDtpmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasDtpmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtpmv_switch_fn; +//static const struct DynamicFnEntry clblasDtpmv_definition = { "clblasDtpmv", (void**)&clblasDtpmv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasDtpsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasDtpsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtpsv_switch_fn; +//static const struct DynamicFnEntry clblasDtpsv_definition = { "clblasDtpsv", (void**)&clblasDtpsv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasDtrmm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, cl_double p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasDtrmm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, cl_double, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtrmm_switch_fn; +//static const struct DynamicFnEntry clblasDtrmm_definition = { "clblasDtrmm", (void**)&clblasDtrmm}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasDtrmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasDtrmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtrmv_switch_fn; +//static const struct DynamicFnEntry clblasDtrmv_definition = { "clblasDtrmv", (void**)&clblasDtrmv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasDtrsm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, cl_double p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasDtrsm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, cl_double, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtrsm_switch_fn; +//static const struct DynamicFnEntry clblasDtrsm_definition = { "clblasDtrsm", (void**)&clblasDtrsm}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasDtrsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasDtrsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDtrsv_switch_fn; +//static const struct DynamicFnEntry clblasDtrsv_definition = { "clblasDtrsv", (void**)&clblasDtrsv}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasDzasum, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasDzasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDzasum_switch_fn; +//static const struct DynamicFnEntry clblasDzasum_definition = { "clblasDzasum", (void**)&clblasDzasum}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasDznrm2, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasDznrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasDznrm2_switch_fn; +//static const struct DynamicFnEntry clblasDznrm2_definition = { "clblasDznrm2", (void**)&clblasDznrm2}; + +//openclamdblas_fn3(OPENCLAMDBLAS_FN_clblasGetVersion, clblasStatus, (cl_uint* p1, cl_uint* p2, cl_uint* p3)) +//clblasStatus (*clblasGetVersion)(cl_uint*, cl_uint*, cl_uint*) = +// OPENCLAMDBLAS_FN_clblasGetVersion_switch_fn; +//static const struct DynamicFnEntry clblasGetVersion_definition = { "clblasGetVersion", (void**)&clblasGetVersion}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasSasum, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasSasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSasum_switch_fn; +//static const struct DynamicFnEntry clblasSasum_definition = { "clblasSasum", (void**)&clblasSasum}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasSaxpy, clblasStatus, (size_t p1, cl_float p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasSaxpy)(size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSaxpy_switch_fn; +//static const struct DynamicFnEntry clblasSaxpy_definition = { "clblasSaxpy", (void**)&clblasSaxpy}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasScasum, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasScasum)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasScasum_switch_fn; +//static const struct DynamicFnEntry clblasScasum_definition = { "clblasScasum", (void**)&clblasScasum}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasScnrm2, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasScnrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasScnrm2_switch_fn; +//static const struct DynamicFnEntry clblasScnrm2_definition = { "clblasScnrm2", (void**)&clblasScnrm2}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasScopy, clblasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasScopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasScopy_switch_fn; +//static const struct DynamicFnEntry clblasScopy_definition = { "clblasScopy", (void**)&clblasScopy}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasSdot, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasSdot)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSdot_switch_fn; +//static const struct DynamicFnEntry clblasSdot_definition = { "clblasSdot", (void**)&clblasSdot}; + +openclamdblas_fn0(OPENCLAMDBLAS_FN_clblasSetup, clblasStatus, ()) +clblasStatus (*clblasSetup)() = + OPENCLAMDBLAS_FN_clblasSetup_switch_fn; +static const struct DynamicFnEntry clblasSetup_definition = { "clblasSetup", (void**)&clblasSetup}; + +//openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasSgbmv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_float p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_float p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +//clblasStatus (*clblasSgbmv)(clblasOrder, clblasTranspose, size_t, size_t, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSgbmv_switch_fn; +//static const struct DynamicFnEntry clblasSgbmv_definition = { "clblasSgbmv", (void**)&clblasSgbmv}; + +openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasSgemm, clblasStatus, (clblasOrder p1, clblasTranspose p2, clblasTranspose p3, size_t p4, size_t p5, size_t p6, cl_float p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, cl_float p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +clblasStatus (*clblasSgemm)(clblasOrder, clblasTranspose, clblasTranspose, size_t, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = + OPENCLAMDBLAS_FN_clblasSgemm_switch_fn; +static const struct DynamicFnEntry clblasSgemm_definition = { "clblasSgemm", (void**)&clblasSgemm}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasSgemv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, cl_float p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_float p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasSgemv)(clblasOrder, clblasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSgemv_switch_fn; +//static const struct DynamicFnEntry clblasSgemv_definition = { "clblasSgemv", (void**)&clblasSgemv}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasSger, clblasStatus, (clblasOrder p1, size_t p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasSger)(clblasOrder, size_t, size_t, cl_float, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSger_switch_fn; +//static const struct DynamicFnEntry clblasSger_definition = { "clblasSger", (void**)&clblasSger}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasSnrm2, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasSnrm2)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSnrm2_switch_fn; +//static const struct DynamicFnEntry clblasSnrm2_definition = { "clblasSnrm2", (void**)&clblasSnrm2}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasSrot, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_float p8, cl_float p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasSrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_float, cl_float, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSrot_switch_fn; +//static const struct DynamicFnEntry clblasSrot_definition = { "clblasSrot", (void**)&clblasSrot}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasSrotg, clblasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasSrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSrotg_switch_fn; +//static const struct DynamicFnEntry clblasSrotg_definition = { "clblasSrotg", (void**)&clblasSrotg}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasSrotm, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasSrotm)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, const cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSrotm_switch_fn; +//static const struct DynamicFnEntry clblasSrotm_definition = { "clblasSrotm", (void**)&clblasSrotm}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasSrotmg, clblasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, const cl_mem p7, size_t p8, cl_mem p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasSrotmg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, const cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSrotmg_switch_fn; +//static const struct DynamicFnEntry clblasSrotmg_definition = { "clblasSrotmg", (void**)&clblasSrotmg}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasSsbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, size_t p4, cl_float p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_float p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasSsbmv)(clblasOrder, clblasUplo, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsbmv_switch_fn; +//static const struct DynamicFnEntry clblasSsbmv_definition = { "clblasSsbmv", (void**)&clblasSsbmv}; + +//openclamdblas_fn10(OPENCLAMDBLAS_FN_clblasSscal, clblasStatus, (size_t p1, cl_float p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) +//clblasStatus (*clblasSscal)(size_t, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSscal_switch_fn; +//static const struct DynamicFnEntry clblasSscal_definition = { "clblasSscal", (void**)&clblasSscal}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasSspmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_float p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasSspmv)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSspmv_switch_fn; +//static const struct DynamicFnEntry clblasSspmv_definition = { "clblasSspmv", (void**)&clblasSspmv}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasSspr, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasSspr)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSspr_switch_fn; +//static const struct DynamicFnEntry clblasSspr_definition = { "clblasSspr", (void**)&clblasSspr}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasSspr2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasSspr2)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSspr2_switch_fn; +//static const struct DynamicFnEntry clblasSspr2_definition = { "clblasSspr2", (void**)&clblasSspr2}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasSswap, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasSswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSswap_switch_fn; +//static const struct DynamicFnEntry clblasSswap_definition = { "clblasSswap", (void**)&clblasSswap}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasSsymm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasSsymm)(clblasOrder, clblasSide, clblasUplo, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsymm_switch_fn; +//static const struct DynamicFnEntry clblasSsymm_definition = { "clblasSsymm", (void**)&clblasSsymm}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasSsymv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, cl_float p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasSsymv)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_float, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsymv_switch_fn; +//static const struct DynamicFnEntry clblasSsymv_definition = { "clblasSsymv", (void**)&clblasSsymv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasSsyr, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasSsyr)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsyr_switch_fn; +//static const struct DynamicFnEntry clblasSsyr_definition = { "clblasSsyr", (void**)&clblasSsyr}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasSsyr2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_float p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasSsyr2)(clblasOrder, clblasUplo, size_t, cl_float, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsyr2_switch_fn; +//static const struct DynamicFnEntry clblasSsyr2_definition = { "clblasSsyr2", (void**)&clblasSsyr2}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasSsyr2k, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_float p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasSsyr2k)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsyr2k_switch_fn; +//static const struct DynamicFnEntry clblasSsyr2k_definition = { "clblasSsyr2k", (void**)&clblasSsyr2k}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasSsyrk, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, cl_float p6, const cl_mem p7, size_t p8, size_t p9, cl_float p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasSsyrk)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, cl_float, const cl_mem, size_t, size_t, cl_float, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasSsyrk_switch_fn; +//static const struct DynamicFnEntry clblasSsyrk_definition = { "clblasSsyrk", (void**)&clblasSsyrk}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasStbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasStbmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStbmv_switch_fn; +//static const struct DynamicFnEntry clblasStbmv_definition = { "clblasStbmv", (void**)&clblasStbmv}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasStbsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasStbsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStbsv_switch_fn; +//static const struct DynamicFnEntry clblasStbsv_definition = { "clblasStbsv", (void**)&clblasStbsv}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasStpmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasStpmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStpmv_switch_fn; +//static const struct DynamicFnEntry clblasStpmv_definition = { "clblasStpmv", (void**)&clblasStpmv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasStpsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasStpsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStpsv_switch_fn; +//static const struct DynamicFnEntry clblasStpsv_definition = { "clblasStpsv", (void**)&clblasStpsv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasStrmm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, cl_float p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasStrmm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, cl_float, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStrmm_switch_fn; +//static const struct DynamicFnEntry clblasStrmm_definition = { "clblasStrmm", (void**)&clblasStrmm}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasStrmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasStrmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStrmv_switch_fn; +//static const struct DynamicFnEntry clblasStrmv_definition = { "clblasStrmv", (void**)&clblasStrmv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasStrsm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, cl_float p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasStrsm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, cl_float, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStrsm_switch_fn; +//static const struct DynamicFnEntry clblasStrsm_definition = { "clblasStrsm", (void**)&clblasStrsm}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasStrsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasStrsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasStrsv_switch_fn; +//static const struct DynamicFnEntry clblasStrsv_definition = { "clblasStrsv", (void**)&clblasStrsv}; + +openclamdblas_fn0(OPENCLAMDBLAS_FN_clblasTeardown, void, ()) +void (*clblasTeardown)() = + OPENCLAMDBLAS_FN_clblasTeardown_switch_fn; +static const struct DynamicFnEntry clblasTeardown_definition = { "clblasTeardown", (void**)&clblasTeardown}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasZaxpy, clblasStatus, (size_t p1, cl_double2 p2, const cl_mem p3, size_t p4, int p5, cl_mem p6, size_t p7, int p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasZaxpy)(size_t, cl_double2, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZaxpy_switch_fn; +//static const struct DynamicFnEntry clblasZaxpy_definition = { "clblasZaxpy", (void**)&clblasZaxpy}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasZcopy, clblasStatus, (size_t p1, const cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasZcopy)(size_t, const cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZcopy_switch_fn; +//static const struct DynamicFnEntry clblasZcopy_definition = { "clblasZcopy", (void**)&clblasZcopy}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasZdotc, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasZdotc)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZdotc_switch_fn; +//static const struct DynamicFnEntry clblasZdotc_definition = { "clblasZdotc", (void**)&clblasZdotc}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasZdotu, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, const cl_mem p7, size_t p8, int p9, cl_mem p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasZdotu)(size_t, cl_mem, size_t, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZdotu_switch_fn; +//static const struct DynamicFnEntry clblasZdotu_definition = { "clblasZdotu", (void**)&clblasZdotu}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasZdrot, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_double p8, cl_double p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasZdrot)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_double, cl_double, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZdrot_switch_fn; +//static const struct DynamicFnEntry clblasZdrot_definition = { "clblasZdrot", (void**)&clblasZdrot}; + +//openclamdblas_fn10(OPENCLAMDBLAS_FN_clblasZdscal, clblasStatus, (size_t p1, cl_double p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) +//clblasStatus (*clblasZdscal)(size_t, cl_double, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZdscal_switch_fn; +//static const struct DynamicFnEntry clblasZdscal_definition = { "clblasZdscal", (void**)&clblasZdscal}; + +//openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasZgbmv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, size_t p5, size_t p6, cl_double2 p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, int p13, cl_double2 p14, cl_mem p15, size_t p16, int p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +//clblasStatus (*clblasZgbmv)(clblasOrder, clblasTranspose, size_t, size_t, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZgbmv_switch_fn; +//static const struct DynamicFnEntry clblasZgbmv_definition = { "clblasZgbmv", (void**)&clblasZgbmv}; + +openclamdblas_fn22(OPENCLAMDBLAS_FN_clblasZgemm, clblasStatus, (clblasOrder p1, clblasTranspose p2, clblasTranspose p3, size_t p4, size_t p5, size_t p6, DoubleComplex p7, const cl_mem p8, size_t p9, size_t p10, const cl_mem p11, size_t p12, size_t p13, DoubleComplex p14, cl_mem p15, size_t p16, size_t p17, cl_uint p18, cl_command_queue* p19, cl_uint p20, const cl_event* p21, cl_event* p22)) +clblasStatus (*clblasZgemm)(clblasOrder, clblasTranspose, clblasTranspose, size_t, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, DoubleComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = + OPENCLAMDBLAS_FN_clblasZgemm_switch_fn; +static const struct DynamicFnEntry clblasZgemm_definition = { "clblasZgemm", (void**)&clblasZgemm}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasZgemv, clblasStatus, (clblasOrder p1, clblasTranspose p2, size_t p3, size_t p4, DoubleComplex p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, DoubleComplex p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasZgemv)(clblasOrder, clblasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, DoubleComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZgemv_switch_fn; +//static const struct DynamicFnEntry clblasZgemv_definition = { "clblasZgemv", (void**)&clblasZgemv}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZgerc, clblasStatus, (clblasOrder p1, size_t p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZgerc)(clblasOrder, size_t, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZgerc_switch_fn; +//static const struct DynamicFnEntry clblasZgerc_definition = { "clblasZgerc", (void**)&clblasZgerc}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZgeru, clblasStatus, (clblasOrder p1, size_t p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZgeru)(clblasOrder, size_t, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZgeru_switch_fn; +//static const struct DynamicFnEntry clblasZgeru_definition = { "clblasZgeru", (void**)&clblasZgeru}; + +//openclamdblas_fn20(OPENCLAMDBLAS_FN_clblasZhbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, size_t p4, cl_double2 p5, const cl_mem p6, size_t p7, size_t p8, const cl_mem p9, size_t p10, int p11, cl_double2 p12, cl_mem p13, size_t p14, int p15, cl_uint p16, cl_command_queue* p17, cl_uint p18, const cl_event* p19, cl_event* p20)) +//clblasStatus (*clblasZhbmv)(clblasOrder, clblasUplo, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, int, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZhbmv_switch_fn; +//static const struct DynamicFnEntry clblasZhbmv_definition = { "clblasZhbmv", (void**)&clblasZhbmv}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasZhemm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, size_t p4, size_t p5, cl_double2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasZhemm)(clblasOrder, clblasSide, clblasUplo, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZhemm_switch_fn; +//static const struct DynamicFnEntry clblasZhemm_definition = { "clblasZhemm", (void**)&clblasZhemm}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasZhemv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, DoubleComplex p4, const cl_mem p5, size_t p6, size_t p7, const cl_mem p8, size_t p9, int p10, DoubleComplex p11, cl_mem p12, size_t p13, int p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasZhemv)(clblasOrder, clblasUplo, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, int, DoubleComplex, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZhemv_switch_fn; +//static const struct DynamicFnEntry clblasZhemv_definition = { "clblasZhemv", (void**)&clblasZhemv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasZher, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, size_t p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasZher)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZher_switch_fn; +//static const struct DynamicFnEntry clblasZher_definition = { "clblasZher", (void**)&clblasZher}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZher2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZher2)(clblasOrder, clblasUplo, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZher2_switch_fn; +//static const struct DynamicFnEntry clblasZher2_definition = { "clblasZher2", (void**)&clblasZher2}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasZher2k, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasZher2k)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZher2k_switch_fn; +//static const struct DynamicFnEntry clblasZher2k_definition = { "clblasZher2k", (void**)&clblasZher2k}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZherk, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, double p6, const cl_mem p7, size_t p8, size_t p9, double p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZherk)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, double, const cl_mem, size_t, size_t, double, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZherk_switch_fn; +//static const struct DynamicFnEntry clblasZherk_definition = { "clblasZherk", (void**)&clblasZherk}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZhpmv, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, const cl_mem p7, size_t p8, int p9, cl_double2 p10, cl_mem p11, size_t p12, int p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZhpmv)(clblasOrder, clblasUplo, size_t, cl_double2, const cl_mem, size_t, const cl_mem, size_t, int, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZhpmv_switch_fn; +//static const struct DynamicFnEntry clblasZhpmv_definition = { "clblasZhpmv", (void**)&clblasZhpmv}; + +//openclamdblas_fn14(OPENCLAMDBLAS_FN_clblasZhpr, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double p4, const cl_mem p5, size_t p6, int p7, cl_mem p8, size_t p9, cl_uint p10, cl_command_queue* p11, cl_uint p12, const cl_event* p13, cl_event* p14)) +//clblasStatus (*clblasZhpr)(clblasOrder, clblasUplo, size_t, cl_double, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZhpr_switch_fn; +//static const struct DynamicFnEntry clblasZhpr_definition = { "clblasZhpr", (void**)&clblasZhpr}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasZhpr2, clblasStatus, (clblasOrder p1, clblasUplo p2, size_t p3, cl_double2 p4, const cl_mem p5, size_t p6, int p7, const cl_mem p8, size_t p9, int p10, cl_mem p11, size_t p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasZhpr2)(clblasOrder, clblasUplo, size_t, cl_double2, const cl_mem, size_t, int, const cl_mem, size_t, int, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZhpr2_switch_fn; +//static const struct DynamicFnEntry clblasZhpr2_definition = { "clblasZhpr2", (void**)&clblasZhpr2}; + +//openclamdblas_fn13(OPENCLAMDBLAS_FN_clblasZrotg, clblasStatus, (cl_mem p1, size_t p2, cl_mem p3, size_t p4, cl_mem p5, size_t p6, cl_mem p7, size_t p8, cl_uint p9, cl_command_queue* p10, cl_uint p11, const cl_event* p12, cl_event* p13)) +//clblasStatus (*clblasZrotg)(cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_mem, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZrotg_switch_fn; +//static const struct DynamicFnEntry clblasZrotg_definition = { "clblasZrotg", (void**)&clblasZrotg}; + +//openclamdblas_fn10(OPENCLAMDBLAS_FN_clblasZscal, clblasStatus, (size_t p1, cl_double2 p2, cl_mem p3, size_t p4, int p5, cl_uint p6, cl_command_queue* p7, cl_uint p8, const cl_event* p9, cl_event* p10)) +//clblasStatus (*clblasZscal)(size_t, cl_double2, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZscal_switch_fn; +//static const struct DynamicFnEntry clblasZscal_definition = { "clblasZscal", (void**)&clblasZscal}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasZswap, clblasStatus, (size_t p1, cl_mem p2, size_t p3, int p4, cl_mem p5, size_t p6, int p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasZswap)(size_t, cl_mem, size_t, int, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZswap_switch_fn; +//static const struct DynamicFnEntry clblasZswap_definition = { "clblasZswap", (void**)&clblasZswap}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasZsymm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, size_t p4, size_t p5, cl_double2 p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, cl_double2 p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasZsymm)(clblasOrder, clblasSide, clblasUplo, size_t, size_t, cl_double2, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, cl_double2, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZsymm_switch_fn; +//static const struct DynamicFnEntry clblasZsymm_definition = { "clblasZsymm", (void**)&clblasZsymm}; + +//openclamdblas_fn21(OPENCLAMDBLAS_FN_clblasZsyr2k, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, size_t p9, const cl_mem p10, size_t p11, size_t p12, DoubleComplex p13, cl_mem p14, size_t p15, size_t p16, cl_uint p17, cl_command_queue* p18, cl_uint p19, const cl_event* p20, cl_event* p21)) +//clblasStatus (*clblasZsyr2k)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, const cl_mem, size_t, size_t, DoubleComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZsyr2k_switch_fn; +//static const struct DynamicFnEntry clblasZsyr2k_definition = { "clblasZsyr2k", (void**)&clblasZsyr2k}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZsyrk, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, size_t p4, size_t p5, DoubleComplex p6, const cl_mem p7, size_t p8, size_t p9, DoubleComplex p10, cl_mem p11, size_t p12, size_t p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZsyrk)(clblasOrder, clblasUplo, clblasTranspose, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, DoubleComplex, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZsyrk_switch_fn; +//static const struct DynamicFnEntry clblasZsyrk_definition = { "clblasZsyrk", (void**)&clblasZsyrk}; + +//openclamdblas_fn18(OPENCLAMDBLAS_FN_clblasZtbmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_mem p13, cl_uint p14, cl_command_queue* p15, cl_uint p16, const cl_event* p17, cl_event* p18)) +//clblasStatus (*clblasZtbmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtbmv_switch_fn; +//static const struct DynamicFnEntry clblasZtbmv_definition = { "clblasZtbmv", (void**)&clblasZtbmv}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasZtbsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, size_t p6, const cl_mem p7, size_t p8, size_t p9, cl_mem p10, size_t p11, int p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasZtbsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtbsv_switch_fn; +//static const struct DynamicFnEntry clblasZtbsv_definition = { "clblasZtbsv", (void**)&clblasZtbsv}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasZtpmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_mem p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasZtpmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtpmv_switch_fn; +//static const struct DynamicFnEntry clblasZtpmv_definition = { "clblasZtpmv", (void**)&clblasZtpmv}; + +//openclamdblas_fn15(OPENCLAMDBLAS_FN_clblasZtpsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, cl_mem p8, size_t p9, int p10, cl_uint p11, cl_command_queue* p12, cl_uint p13, const cl_event* p14, cl_event* p15)) +//clblasStatus (*clblasZtpsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtpsv_switch_fn; +//static const struct DynamicFnEntry clblasZtpsv_definition = { "clblasZtpsv", (void**)&clblasZtpsv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasZtrmm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, DoubleComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasZtrmm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtrmm_switch_fn; +//static const struct DynamicFnEntry clblasZtrmm_definition = { "clblasZtrmm", (void**)&clblasZtrmm}; + +//openclamdblas_fn17(OPENCLAMDBLAS_FN_clblasZtrmv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_mem p12, cl_uint p13, cl_command_queue* p14, cl_uint p15, const cl_event* p16, cl_event* p17)) +//clblasStatus (*clblasZtrmv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtrmv_switch_fn; +//static const struct DynamicFnEntry clblasZtrmv_definition = { "clblasZtrmv", (void**)&clblasZtrmv}; + +//openclamdblas_fn19(OPENCLAMDBLAS_FN_clblasZtrsm, clblasStatus, (clblasOrder p1, clblasSide p2, clblasUplo p3, clblasTranspose p4, clblasDiag p5, size_t p6, size_t p7, DoubleComplex p8, const cl_mem p9, size_t p10, size_t p11, cl_mem p12, size_t p13, size_t p14, cl_uint p15, cl_command_queue* p16, cl_uint p17, const cl_event* p18, cl_event* p19)) +//clblasStatus (*clblasZtrsm)(clblasOrder, clblasSide, clblasUplo, clblasTranspose, clblasDiag, size_t, size_t, DoubleComplex, const cl_mem, size_t, size_t, cl_mem, size_t, size_t, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtrsm_switch_fn; +//static const struct DynamicFnEntry clblasZtrsm_definition = { "clblasZtrsm", (void**)&clblasZtrsm}; + +//openclamdblas_fn16(OPENCLAMDBLAS_FN_clblasZtrsv, clblasStatus, (clblasOrder p1, clblasUplo p2, clblasTranspose p3, clblasDiag p4, size_t p5, const cl_mem p6, size_t p7, size_t p8, cl_mem p9, size_t p10, int p11, cl_uint p12, cl_command_queue* p13, cl_uint p14, const cl_event* p15, cl_event* p16)) +//clblasStatus (*clblasZtrsv)(clblasOrder, clblasUplo, clblasTranspose, clblasDiag, size_t, const cl_mem, size_t, size_t, cl_mem, size_t, int, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasZtrsv_switch_fn; +//static const struct DynamicFnEntry clblasZtrsv_definition = { "clblasZtrsv", (void**)&clblasZtrsv}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasiCamax, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasiCamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasiCamax_switch_fn; +//static const struct DynamicFnEntry clblasiCamax_definition = { "clblasiCamax", (void**)&clblasiCamax}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasiDamax, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasiDamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasiDamax_switch_fn; +//static const struct DynamicFnEntry clblasiDamax_definition = { "clblasiDamax", (void**)&clblasiDamax}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasiSamax, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasiSamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasiSamax_switch_fn; +//static const struct DynamicFnEntry clblasiSamax_definition = { "clblasiSamax", (void**)&clblasiSamax}; + +//openclamdblas_fn12(OPENCLAMDBLAS_FN_clblasiZamax, clblasStatus, (size_t p1, cl_mem p2, size_t p3, const cl_mem p4, size_t p5, int p6, cl_mem p7, cl_uint p8, cl_command_queue* p9, cl_uint p10, const cl_event* p11, cl_event* p12)) +//clblasStatus (*clblasiZamax)(size_t, cl_mem, size_t, const cl_mem, size_t, int, cl_mem, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*) = +// OPENCLAMDBLAS_FN_clblasiZamax_switch_fn; +//static const struct DynamicFnEntry clblasiZamax_definition = { "clblasiZamax", (void**)&clblasiZamax}; + + +// generated by parser_clblas.py +static const struct DynamicFnEntry* openclamdblas_fn[] = { + NULL/*&clblasCaxpy_definition*/, + NULL/*&clblasCcopy_definition*/, + NULL/*&clblasCdotc_definition*/, + NULL/*&clblasCdotu_definition*/, + NULL/*&clblasCgbmv_definition*/, + &clblasCgemm_definition, + NULL/*&clblasCgemv_definition*/, + NULL/*&clblasCgerc_definition*/, + NULL/*&clblasCgeru_definition*/, + NULL/*&clblasChbmv_definition*/, + NULL/*&clblasChemm_definition*/, + NULL/*&clblasChemv_definition*/, + NULL/*&clblasCher_definition*/, + NULL/*&clblasCher2_definition*/, + NULL/*&clblasCher2k_definition*/, + NULL/*&clblasCherk_definition*/, + NULL/*&clblasChpmv_definition*/, + NULL/*&clblasChpr_definition*/, + NULL/*&clblasChpr2_definition*/, + NULL/*&clblasCrotg_definition*/, + NULL/*&clblasCscal_definition*/, + NULL/*&clblasCsrot_definition*/, + NULL/*&clblasCsscal_definition*/, + NULL/*&clblasCswap_definition*/, + NULL/*&clblasCsymm_definition*/, + NULL/*&clblasCsyr2k_definition*/, + NULL/*&clblasCsyrk_definition*/, + NULL/*&clblasCtbmv_definition*/, + NULL/*&clblasCtbsv_definition*/, + NULL/*&clblasCtpmv_definition*/, + NULL/*&clblasCtpsv_definition*/, + NULL/*&clblasCtrmm_definition*/, + NULL/*&clblasCtrmv_definition*/, + NULL/*&clblasCtrsm_definition*/, + NULL/*&clblasCtrsv_definition*/, + NULL/*&clblasDasum_definition*/, + NULL/*&clblasDaxpy_definition*/, + NULL/*&clblasDcopy_definition*/, + NULL/*&clblasDdot_definition*/, + NULL/*&clblasDgbmv_definition*/, + &clblasDgemm_definition, + NULL/*&clblasDgemv_definition*/, + NULL/*&clblasDger_definition*/, + NULL/*&clblasDnrm2_definition*/, + NULL/*&clblasDrot_definition*/, + NULL/*&clblasDrotg_definition*/, + NULL/*&clblasDrotm_definition*/, + NULL/*&clblasDrotmg_definition*/, + NULL/*&clblasDsbmv_definition*/, + NULL/*&clblasDscal_definition*/, + NULL/*&clblasDspmv_definition*/, + NULL/*&clblasDspr_definition*/, + NULL/*&clblasDspr2_definition*/, + NULL/*&clblasDswap_definition*/, + NULL/*&clblasDsymm_definition*/, + NULL/*&clblasDsymv_definition*/, + NULL/*&clblasDsyr_definition*/, + NULL/*&clblasDsyr2_definition*/, + NULL/*&clblasDsyr2k_definition*/, + NULL/*&clblasDsyrk_definition*/, + NULL/*&clblasDtbmv_definition*/, + NULL/*&clblasDtbsv_definition*/, + NULL/*&clblasDtpmv_definition*/, + NULL/*&clblasDtpsv_definition*/, + NULL/*&clblasDtrmm_definition*/, + NULL/*&clblasDtrmv_definition*/, + NULL/*&clblasDtrsm_definition*/, + NULL/*&clblasDtrsv_definition*/, + NULL/*&clblasDzasum_definition*/, + NULL/*&clblasDznrm2_definition*/, + NULL/*&clblasGetVersion_definition*/, + NULL/*&clblasSasum_definition*/, + NULL/*&clblasSaxpy_definition*/, + NULL/*&clblasScasum_definition*/, + NULL/*&clblasScnrm2_definition*/, + NULL/*&clblasScopy_definition*/, + NULL/*&clblasSdot_definition*/, + &clblasSetup_definition, + NULL/*&clblasSgbmv_definition*/, + &clblasSgemm_definition, + NULL/*&clblasSgemv_definition*/, + NULL/*&clblasSger_definition*/, + NULL/*&clblasSnrm2_definition*/, + NULL/*&clblasSrot_definition*/, + NULL/*&clblasSrotg_definition*/, + NULL/*&clblasSrotm_definition*/, + NULL/*&clblasSrotmg_definition*/, + NULL/*&clblasSsbmv_definition*/, + NULL/*&clblasSscal_definition*/, + NULL/*&clblasSspmv_definition*/, + NULL/*&clblasSspr_definition*/, + NULL/*&clblasSspr2_definition*/, + NULL/*&clblasSswap_definition*/, + NULL/*&clblasSsymm_definition*/, + NULL/*&clblasSsymv_definition*/, + NULL/*&clblasSsyr_definition*/, + NULL/*&clblasSsyr2_definition*/, + NULL/*&clblasSsyr2k_definition*/, + NULL/*&clblasSsyrk_definition*/, + NULL/*&clblasStbmv_definition*/, + NULL/*&clblasStbsv_definition*/, + NULL/*&clblasStpmv_definition*/, + NULL/*&clblasStpsv_definition*/, + NULL/*&clblasStrmm_definition*/, + NULL/*&clblasStrmv_definition*/, + NULL/*&clblasStrsm_definition*/, + NULL/*&clblasStrsv_definition*/, + &clblasTeardown_definition, + NULL/*&clblasZaxpy_definition*/, + NULL/*&clblasZcopy_definition*/, + NULL/*&clblasZdotc_definition*/, + NULL/*&clblasZdotu_definition*/, + NULL/*&clblasZdrot_definition*/, + NULL/*&clblasZdscal_definition*/, + NULL/*&clblasZgbmv_definition*/, + &clblasZgemm_definition, + NULL/*&clblasZgemv_definition*/, + NULL/*&clblasZgerc_definition*/, + NULL/*&clblasZgeru_definition*/, + NULL/*&clblasZhbmv_definition*/, + NULL/*&clblasZhemm_definition*/, + NULL/*&clblasZhemv_definition*/, + NULL/*&clblasZher_definition*/, + NULL/*&clblasZher2_definition*/, + NULL/*&clblasZher2k_definition*/, + NULL/*&clblasZherk_definition*/, + NULL/*&clblasZhpmv_definition*/, + NULL/*&clblasZhpr_definition*/, + NULL/*&clblasZhpr2_definition*/, + NULL/*&clblasZrotg_definition*/, + NULL/*&clblasZscal_definition*/, + NULL/*&clblasZswap_definition*/, + NULL/*&clblasZsymm_definition*/, + NULL/*&clblasZsyr2k_definition*/, + NULL/*&clblasZsyrk_definition*/, + NULL/*&clblasZtbmv_definition*/, + NULL/*&clblasZtbsv_definition*/, + NULL/*&clblasZtpmv_definition*/, + NULL/*&clblasZtpsv_definition*/, + NULL/*&clblasZtrmm_definition*/, + NULL/*&clblasZtrmv_definition*/, + NULL/*&clblasZtrsm_definition*/, + NULL/*&clblasZtrsv_definition*/, + NULL/*&clblasiCamax_definition*/, + NULL/*&clblasiDamax_definition*/, + NULL/*&clblasiSamax_definition*/, + NULL/*&clblasiZamax_definition*/, +}; + +// number of enabled functions: 6 diff --git a/modules/core/src/opencl/runtime/autogenerated/opencl_clfft_impl.hpp b/modules/core/src/opencl/runtime/autogenerated/opencl_clfft_impl.hpp new file mode 100644 index 000000000000..9876582fa0b2 --- /dev/null +++ b/modules/core/src/opencl/runtime/autogenerated/opencl_clfft_impl.hpp @@ -0,0 +1,364 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +// generated by parser_clfft.py +enum OPENCLAMDFFT_FN_ID { + OPENCLAMDFFT_FN_clfftBakePlan = 0, +// OPENCLAMDFFT_FN_clfftCopyPlan = 1, + OPENCLAMDFFT_FN_clfftCreateDefaultPlan = 2, + OPENCLAMDFFT_FN_clfftDestroyPlan = 3, + OPENCLAMDFFT_FN_clfftEnqueueTransform = 4, +// OPENCLAMDFFT_FN_clfftGetLayout = 5, +// OPENCLAMDFFT_FN_clfftGetPlanBatchSize = 6, +// OPENCLAMDFFT_FN_clfftGetPlanContext = 7, +// OPENCLAMDFFT_FN_clfftGetPlanDim = 8, +// OPENCLAMDFFT_FN_clfftGetPlanDistance = 9, +// OPENCLAMDFFT_FN_clfftGetPlanInStride = 10, +// OPENCLAMDFFT_FN_clfftGetPlanLength = 11, +// OPENCLAMDFFT_FN_clfftGetPlanOutStride = 12, +// OPENCLAMDFFT_FN_clfftGetPlanPrecision = 13, +// OPENCLAMDFFT_FN_clfftGetPlanScale = 14, +// OPENCLAMDFFT_FN_clfftGetPlanTransposeResult = 15, +// OPENCLAMDFFT_FN_clfftGetResultLocation = 16, + OPENCLAMDFFT_FN_clfftGetTmpBufSize = 17, + OPENCLAMDFFT_FN_clfftGetVersion = 18, + OPENCLAMDFFT_FN_clfftSetLayout = 19, + OPENCLAMDFFT_FN_clfftSetPlanBatchSize = 20, +// OPENCLAMDFFT_FN_clfftSetPlanCallback = 21, +// OPENCLAMDFFT_FN_clfftSetPlanDim = 22, + OPENCLAMDFFT_FN_clfftSetPlanDistance = 23, + OPENCLAMDFFT_FN_clfftSetPlanInStride = 24, +// OPENCLAMDFFT_FN_clfftSetPlanLength = 25, + OPENCLAMDFFT_FN_clfftSetPlanOutStride = 26, + OPENCLAMDFFT_FN_clfftSetPlanPrecision = 27, + OPENCLAMDFFT_FN_clfftSetPlanScale = 28, +// OPENCLAMDFFT_FN_clfftSetPlanTransposeResult = 29, + OPENCLAMDFFT_FN_clfftSetResultLocation = 30, + OPENCLAMDFFT_FN_clfftSetup = 31, + OPENCLAMDFFT_FN_clfftTeardown = 32, +}; + +namespace { +// generated by parser_clfft.py +#define openclamdfft_fn0(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(); } \ + +#define openclamdfft_fn1(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1); } \ + +#define openclamdfft_fn2(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2); } \ + +#define openclamdfft_fn3(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3); } \ + +#define openclamdfft_fn4(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4); } \ + +#define openclamdfft_fn5(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5); } \ + +#define openclamdfft_fn6(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6); } \ + +#define openclamdfft_fn7(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7); } \ + +#define openclamdfft_fn8(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8); } \ + +#define openclamdfft_fn9(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } \ + +#define openclamdfft_fn10(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } \ + +#define openclamdfft_fn11(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } \ + +#define openclamdfft_fn12(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } \ + +#define openclamdfft_fn13(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } \ + +#define openclamdfft_fn14(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } \ + +#define openclamdfft_fn15(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } \ + +#define openclamdfft_fn16(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } \ + +#define openclamdfft_fn17(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17); } \ + +#define openclamdfft_fn18(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18); } \ + +#define openclamdfft_fn19(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19); } \ + +#define openclamdfft_fn20(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20); } \ + +#define openclamdfft_fn21(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21); } \ + +#define openclamdfft_fn22(ID, _R, decl_args) \ + typedef _R (*ID##FN)decl_args; \ + static _R ID##_switch_fn decl_args \ + { return ((ID##FN)openclamdfft_check_fn(ID))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22); } \ + +} + +// generated by parser_clfft.py +openclamdfft_fn5(OPENCLAMDFFT_FN_clfftBakePlan, clfftStatus, (clfftPlanHandle p1, cl_uint p2, cl_command_queue* p3, void (CL_CALLBACK*p4) (clfftPlanHandle plHandle, void* user_data), void* p5)) +clfftStatus (*clfftBakePlan)(clfftPlanHandle, cl_uint, cl_command_queue*, void (CL_CALLBACK*) (clfftPlanHandle plHandle, void* user_data), void*) = + OPENCLAMDFFT_FN_clfftBakePlan_switch_fn; +static const struct DynamicFnEntry clfftBakePlan_definition = { "clfftBakePlan", (void**)&clfftBakePlan}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftCopyPlan, clfftStatus, (clfftPlanHandle* p1, cl_context p2, clfftPlanHandle p3)) +//clfftStatus (*clfftCopyPlan)(clfftPlanHandle*, cl_context, clfftPlanHandle) = +// OPENCLAMDFFT_FN_clfftCopyPlan_switch_fn; +//static const struct DynamicFnEntry clfftCopyPlan_definition = { "clfftCopyPlan", (void**)&clfftCopyPlan}; + +openclamdfft_fn4(OPENCLAMDFFT_FN_clfftCreateDefaultPlan, clfftStatus, (clfftPlanHandle* p1, cl_context p2, const clfftDim p3, const size_t* p4)) +clfftStatus (*clfftCreateDefaultPlan)(clfftPlanHandle*, cl_context, const clfftDim, const size_t*) = + OPENCLAMDFFT_FN_clfftCreateDefaultPlan_switch_fn; +static const struct DynamicFnEntry clfftCreateDefaultPlan_definition = { "clfftCreateDefaultPlan", (void**)&clfftCreateDefaultPlan}; + +openclamdfft_fn1(OPENCLAMDFFT_FN_clfftDestroyPlan, clfftStatus, (clfftPlanHandle* p1)) +clfftStatus (*clfftDestroyPlan)(clfftPlanHandle*) = + OPENCLAMDFFT_FN_clfftDestroyPlan_switch_fn; +static const struct DynamicFnEntry clfftDestroyPlan_definition = { "clfftDestroyPlan", (void**)&clfftDestroyPlan}; + +openclamdfft_fn10(OPENCLAMDFFT_FN_clfftEnqueueTransform, clfftStatus, (clfftPlanHandle p1, clfftDirection p2, cl_uint p3, cl_command_queue* p4, cl_uint p5, const cl_event* p6, cl_event* p7, cl_mem* p8, cl_mem* p9, cl_mem p10)) +clfftStatus (*clfftEnqueueTransform)(clfftPlanHandle, clfftDirection, cl_uint, cl_command_queue*, cl_uint, const cl_event*, cl_event*, cl_mem*, cl_mem*, cl_mem) = + OPENCLAMDFFT_FN_clfftEnqueueTransform_switch_fn; +static const struct DynamicFnEntry clfftEnqueueTransform_definition = { "clfftEnqueueTransform", (void**)&clfftEnqueueTransform}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetLayout, clfftStatus, (const clfftPlanHandle p1, clfftLayout* p2, clfftLayout* p3)) +//clfftStatus (*clfftGetLayout)(const clfftPlanHandle, clfftLayout*, clfftLayout*) = +// OPENCLAMDFFT_FN_clfftGetLayout_switch_fn; +//static const struct DynamicFnEntry clfftGetLayout_definition = { "clfftGetLayout", (void**)&clfftGetLayout}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftGetPlanBatchSize, clfftStatus, (const clfftPlanHandle p1, size_t* p2)) +//clfftStatus (*clfftGetPlanBatchSize)(const clfftPlanHandle, size_t*) = +// OPENCLAMDFFT_FN_clfftGetPlanBatchSize_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanBatchSize_definition = { "clfftGetPlanBatchSize", (void**)&clfftGetPlanBatchSize}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftGetPlanContext, clfftStatus, (const clfftPlanHandle p1, cl_context* p2)) +//clfftStatus (*clfftGetPlanContext)(const clfftPlanHandle, cl_context*) = +// OPENCLAMDFFT_FN_clfftGetPlanContext_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanContext_definition = { "clfftGetPlanContext", (void**)&clfftGetPlanContext}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetPlanDim, clfftStatus, (const clfftPlanHandle p1, clfftDim* p2, cl_uint* p3)) +//clfftStatus (*clfftGetPlanDim)(const clfftPlanHandle, clfftDim*, cl_uint*) = +// OPENCLAMDFFT_FN_clfftGetPlanDim_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanDim_definition = { "clfftGetPlanDim", (void**)&clfftGetPlanDim}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetPlanDistance, clfftStatus, (const clfftPlanHandle p1, size_t* p2, size_t* p3)) +//clfftStatus (*clfftGetPlanDistance)(const clfftPlanHandle, size_t*, size_t*) = +// OPENCLAMDFFT_FN_clfftGetPlanDistance_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanDistance_definition = { "clfftGetPlanDistance", (void**)&clfftGetPlanDistance}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetPlanInStride, clfftStatus, (const clfftPlanHandle p1, const clfftDim p2, size_t* p3)) +//clfftStatus (*clfftGetPlanInStride)(const clfftPlanHandle, const clfftDim, size_t*) = +// OPENCLAMDFFT_FN_clfftGetPlanInStride_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanInStride_definition = { "clfftGetPlanInStride", (void**)&clfftGetPlanInStride}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetPlanLength, clfftStatus, (const clfftPlanHandle p1, const clfftDim p2, size_t* p3)) +//clfftStatus (*clfftGetPlanLength)(const clfftPlanHandle, const clfftDim, size_t*) = +// OPENCLAMDFFT_FN_clfftGetPlanLength_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanLength_definition = { "clfftGetPlanLength", (void**)&clfftGetPlanLength}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetPlanOutStride, clfftStatus, (const clfftPlanHandle p1, const clfftDim p2, size_t* p3)) +//clfftStatus (*clfftGetPlanOutStride)(const clfftPlanHandle, const clfftDim, size_t*) = +// OPENCLAMDFFT_FN_clfftGetPlanOutStride_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanOutStride_definition = { "clfftGetPlanOutStride", (void**)&clfftGetPlanOutStride}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftGetPlanPrecision, clfftStatus, (const clfftPlanHandle p1, clfftPrecision* p2)) +//clfftStatus (*clfftGetPlanPrecision)(const clfftPlanHandle, clfftPrecision*) = +// OPENCLAMDFFT_FN_clfftGetPlanPrecision_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanPrecision_definition = { "clfftGetPlanPrecision", (void**)&clfftGetPlanPrecision}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetPlanScale, clfftStatus, (const clfftPlanHandle p1, clfftDirection p2, cl_float* p3)) +//clfftStatus (*clfftGetPlanScale)(const clfftPlanHandle, clfftDirection, cl_float*) = +// OPENCLAMDFFT_FN_clfftGetPlanScale_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanScale_definition = { "clfftGetPlanScale", (void**)&clfftGetPlanScale}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftGetPlanTransposeResult, clfftStatus, (const clfftPlanHandle p1, clfftResultTransposed* p2)) +//clfftStatus (*clfftGetPlanTransposeResult)(const clfftPlanHandle, clfftResultTransposed*) = +// OPENCLAMDFFT_FN_clfftGetPlanTransposeResult_switch_fn; +//static const struct DynamicFnEntry clfftGetPlanTransposeResult_definition = { "clfftGetPlanTransposeResult", (void**)&clfftGetPlanTransposeResult}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftGetResultLocation, clfftStatus, (const clfftPlanHandle p1, clfftResultLocation* p2)) +//clfftStatus (*clfftGetResultLocation)(const clfftPlanHandle, clfftResultLocation*) = +// OPENCLAMDFFT_FN_clfftGetResultLocation_switch_fn; +//static const struct DynamicFnEntry clfftGetResultLocation_definition = { "clfftGetResultLocation", (void**)&clfftGetResultLocation}; + +openclamdfft_fn2(OPENCLAMDFFT_FN_clfftGetTmpBufSize, clfftStatus, (const clfftPlanHandle p1, size_t* p2)) +clfftStatus (*clfftGetTmpBufSize)(const clfftPlanHandle, size_t*) = + OPENCLAMDFFT_FN_clfftGetTmpBufSize_switch_fn; +static const struct DynamicFnEntry clfftGetTmpBufSize_definition = { "clfftGetTmpBufSize", (void**)&clfftGetTmpBufSize}; + +openclamdfft_fn3(OPENCLAMDFFT_FN_clfftGetVersion, clfftStatus, (cl_uint* p1, cl_uint* p2, cl_uint* p3)) +clfftStatus (*clfftGetVersion)(cl_uint*, cl_uint*, cl_uint*) = + OPENCLAMDFFT_FN_clfftGetVersion_switch_fn; +static const struct DynamicFnEntry clfftGetVersion_definition = { "clfftGetVersion", (void**)&clfftGetVersion}; + +openclamdfft_fn3(OPENCLAMDFFT_FN_clfftSetLayout, clfftStatus, (clfftPlanHandle p1, clfftLayout p2, clfftLayout p3)) +clfftStatus (*clfftSetLayout)(clfftPlanHandle, clfftLayout, clfftLayout) = + OPENCLAMDFFT_FN_clfftSetLayout_switch_fn; +static const struct DynamicFnEntry clfftSetLayout_definition = { "clfftSetLayout", (void**)&clfftSetLayout}; + +openclamdfft_fn2(OPENCLAMDFFT_FN_clfftSetPlanBatchSize, clfftStatus, (clfftPlanHandle p1, size_t p2)) +clfftStatus (*clfftSetPlanBatchSize)(clfftPlanHandle, size_t) = + OPENCLAMDFFT_FN_clfftSetPlanBatchSize_switch_fn; +static const struct DynamicFnEntry clfftSetPlanBatchSize_definition = { "clfftSetPlanBatchSize", (void**)&clfftSetPlanBatchSize}; + +//openclamdfft_fn7(OPENCLAMDFFT_FN_clfftSetPlanCallback, clfftStatus, (clfftPlanHandle p1, const char* p2, const char* p3, int p4, clfftCallbackType p5, cl_mem* p6, int p7)) +//clfftStatus (*clfftSetPlanCallback)(clfftPlanHandle, const char*, const char*, int, clfftCallbackType, cl_mem*, int) = +// OPENCLAMDFFT_FN_clfftSetPlanCallback_switch_fn; +//static const struct DynamicFnEntry clfftSetPlanCallback_definition = { "clfftSetPlanCallback", (void**)&clfftSetPlanCallback}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftSetPlanDim, clfftStatus, (clfftPlanHandle p1, const clfftDim p2)) +//clfftStatus (*clfftSetPlanDim)(clfftPlanHandle, const clfftDim) = +// OPENCLAMDFFT_FN_clfftSetPlanDim_switch_fn; +//static const struct DynamicFnEntry clfftSetPlanDim_definition = { "clfftSetPlanDim", (void**)&clfftSetPlanDim}; + +openclamdfft_fn3(OPENCLAMDFFT_FN_clfftSetPlanDistance, clfftStatus, (clfftPlanHandle p1, size_t p2, size_t p3)) +clfftStatus (*clfftSetPlanDistance)(clfftPlanHandle, size_t, size_t) = + OPENCLAMDFFT_FN_clfftSetPlanDistance_switch_fn; +static const struct DynamicFnEntry clfftSetPlanDistance_definition = { "clfftSetPlanDistance", (void**)&clfftSetPlanDistance}; + +openclamdfft_fn3(OPENCLAMDFFT_FN_clfftSetPlanInStride, clfftStatus, (clfftPlanHandle p1, const clfftDim p2, size_t* p3)) +clfftStatus (*clfftSetPlanInStride)(clfftPlanHandle, const clfftDim, size_t*) = + OPENCLAMDFFT_FN_clfftSetPlanInStride_switch_fn; +static const struct DynamicFnEntry clfftSetPlanInStride_definition = { "clfftSetPlanInStride", (void**)&clfftSetPlanInStride}; + +//openclamdfft_fn3(OPENCLAMDFFT_FN_clfftSetPlanLength, clfftStatus, (clfftPlanHandle p1, const clfftDim p2, const size_t* p3)) +//clfftStatus (*clfftSetPlanLength)(clfftPlanHandle, const clfftDim, const size_t*) = +// OPENCLAMDFFT_FN_clfftSetPlanLength_switch_fn; +//static const struct DynamicFnEntry clfftSetPlanLength_definition = { "clfftSetPlanLength", (void**)&clfftSetPlanLength}; + +openclamdfft_fn3(OPENCLAMDFFT_FN_clfftSetPlanOutStride, clfftStatus, (clfftPlanHandle p1, const clfftDim p2, size_t* p3)) +clfftStatus (*clfftSetPlanOutStride)(clfftPlanHandle, const clfftDim, size_t*) = + OPENCLAMDFFT_FN_clfftSetPlanOutStride_switch_fn; +static const struct DynamicFnEntry clfftSetPlanOutStride_definition = { "clfftSetPlanOutStride", (void**)&clfftSetPlanOutStride}; + +openclamdfft_fn2(OPENCLAMDFFT_FN_clfftSetPlanPrecision, clfftStatus, (clfftPlanHandle p1, clfftPrecision p2)) +clfftStatus (*clfftSetPlanPrecision)(clfftPlanHandle, clfftPrecision) = + OPENCLAMDFFT_FN_clfftSetPlanPrecision_switch_fn; +static const struct DynamicFnEntry clfftSetPlanPrecision_definition = { "clfftSetPlanPrecision", (void**)&clfftSetPlanPrecision}; + +openclamdfft_fn3(OPENCLAMDFFT_FN_clfftSetPlanScale, clfftStatus, (clfftPlanHandle p1, clfftDirection p2, cl_float p3)) +clfftStatus (*clfftSetPlanScale)(clfftPlanHandle, clfftDirection, cl_float) = + OPENCLAMDFFT_FN_clfftSetPlanScale_switch_fn; +static const struct DynamicFnEntry clfftSetPlanScale_definition = { "clfftSetPlanScale", (void**)&clfftSetPlanScale}; + +//openclamdfft_fn2(OPENCLAMDFFT_FN_clfftSetPlanTransposeResult, clfftStatus, (clfftPlanHandle p1, clfftResultTransposed p2)) +//clfftStatus (*clfftSetPlanTransposeResult)(clfftPlanHandle, clfftResultTransposed) = +// OPENCLAMDFFT_FN_clfftSetPlanTransposeResult_switch_fn; +//static const struct DynamicFnEntry clfftSetPlanTransposeResult_definition = { "clfftSetPlanTransposeResult", (void**)&clfftSetPlanTransposeResult}; + +openclamdfft_fn2(OPENCLAMDFFT_FN_clfftSetResultLocation, clfftStatus, (clfftPlanHandle p1, clfftResultLocation p2)) +clfftStatus (*clfftSetResultLocation)(clfftPlanHandle, clfftResultLocation) = + OPENCLAMDFFT_FN_clfftSetResultLocation_switch_fn; +static const struct DynamicFnEntry clfftSetResultLocation_definition = { "clfftSetResultLocation", (void**)&clfftSetResultLocation}; + +openclamdfft_fn1(OPENCLAMDFFT_FN_clfftSetup, clfftStatus, (const clfftSetupData* p1)) +clfftStatus (*clfftSetup)(const clfftSetupData*) = + OPENCLAMDFFT_FN_clfftSetup_switch_fn; +static const struct DynamicFnEntry clfftSetup_definition = { "clfftSetup", (void**)&clfftSetup}; + +openclamdfft_fn0(OPENCLAMDFFT_FN_clfftTeardown, clfftStatus, ()) +clfftStatus (*clfftTeardown)() = + OPENCLAMDFFT_FN_clfftTeardown_switch_fn; +static const struct DynamicFnEntry clfftTeardown_definition = { "clfftTeardown", (void**)&clfftTeardown}; + + +// generated by parser_clfft.py +static const struct DynamicFnEntry* openclamdfft_fn[] = { + &clfftBakePlan_definition, + NULL/*&clfftCopyPlan_definition*/, + &clfftCreateDefaultPlan_definition, + &clfftDestroyPlan_definition, + &clfftEnqueueTransform_definition, + NULL/*&clfftGetLayout_definition*/, + NULL/*&clfftGetPlanBatchSize_definition*/, + NULL/*&clfftGetPlanContext_definition*/, + NULL/*&clfftGetPlanDim_definition*/, + NULL/*&clfftGetPlanDistance_definition*/, + NULL/*&clfftGetPlanInStride_definition*/, + NULL/*&clfftGetPlanLength_definition*/, + NULL/*&clfftGetPlanOutStride_definition*/, + NULL/*&clfftGetPlanPrecision_definition*/, + NULL/*&clfftGetPlanScale_definition*/, + NULL/*&clfftGetPlanTransposeResult_definition*/, + NULL/*&clfftGetResultLocation_definition*/, + &clfftGetTmpBufSize_definition, + &clfftGetVersion_definition, + &clfftSetLayout_definition, + &clfftSetPlanBatchSize_definition, + NULL/*&clfftSetPlanCallback_definition*/, + NULL/*&clfftSetPlanDim_definition*/, + &clfftSetPlanDistance_definition, + &clfftSetPlanInStride_definition, + NULL/*&clfftSetPlanLength_definition*/, + &clfftSetPlanOutStride_definition, + &clfftSetPlanPrecision_definition, + &clfftSetPlanScale_definition, + NULL/*&clfftSetPlanTransposeResult_definition*/, + &clfftSetResultLocation_definition, + &clfftSetup_definition, + &clfftTeardown_definition, +}; + +// number of enabled functions: 16 diff --git a/modules/core/src/opencl/runtime/generator/common.py b/modules/core/src/opencl/runtime/generator/common.py index 73fe6b0f47d2..5bfabd29891f 100644 --- a/modules/core/src/opencl/runtime/generator/common.py +++ b/modules/core/src/opencl/runtime/generator/common.py @@ -116,7 +116,7 @@ def readFunctionFilter(fns, fileName): def outputToString(f): def wrapped(*args, **kwargs): - from cStringIO import StringIO + from io import StringIO old_stdout = sys.stdout sys.stdout = str_stdout = StringIO() res = f(*args, **kwargs) diff --git a/modules/core/src/opencl/runtime/generator/filter/opencl_clamdblas_functions.list b/modules/core/src/opencl/runtime/generator/filter/opencl_clamdblas_functions.list deleted file mode 100644 index 2b1f0768ece2..000000000000 --- a/modules/core/src/opencl/runtime/generator/filter/opencl_clamdblas_functions.list +++ /dev/null @@ -1,176 +0,0 @@ -//clAmdBlasAddScratchImage -//clAmdBlasCaxpy -//clAmdBlasCcopy -//clAmdBlasCdotc -//clAmdBlasCdotu -//clAmdBlasCgbmv -//clAmdBlasCgemm -clAmdBlasCgemmEx -//clAmdBlasCgemv -//clAmdBlasCgemvEx -//clAmdBlasCgerc -//clAmdBlasCgeru -//clAmdBlasChbmv -//clAmdBlasChemm -//clAmdBlasChemv -//clAmdBlasCher -//clAmdBlasCher2 -//clAmdBlasCher2k -//clAmdBlasCherk -//clAmdBlasChpmv -//clAmdBlasChpr -//clAmdBlasChpr2 -//clAmdBlasCrotg -//clAmdBlasCscal -//clAmdBlasCsrot -//clAmdBlasCsscal -//clAmdBlasCswap -//clAmdBlasCsymm -//clAmdBlasCsyr2k -//clAmdBlasCsyr2kEx -//clAmdBlasCsyrk -//clAmdBlasCsyrkEx -//clAmdBlasCtbmv -//clAmdBlasCtbsv -//clAmdBlasCtpmv -//clAmdBlasCtpsv -//clAmdBlasCtrmm -//clAmdBlasCtrmmEx -//clAmdBlasCtrmv -//clAmdBlasCtrsm -//clAmdBlasCtrsmEx -//clAmdBlasCtrsv -//clAmdBlasDasum -//clAmdBlasDaxpy -//clAmdBlasDcopy -//clAmdBlasDdot -//clAmdBlasDgbmv -//clAmdBlasDgemm -clAmdBlasDgemmEx -//clAmdBlasDgemv -//clAmdBlasDgemvEx -//clAmdBlasDger -//clAmdBlasDnrm2 -//clAmdBlasDrot -//clAmdBlasDrotg -//clAmdBlasDrotm -//clAmdBlasDrotmg -//clAmdBlasDsbmv -//clAmdBlasDscal -//clAmdBlasDspmv -//clAmdBlasDspr -//clAmdBlasDspr2 -//clAmdBlasDswap -//clAmdBlasDsymm -//clAmdBlasDsymv -//clAmdBlasDsymvEx -//clAmdBlasDsyr -//clAmdBlasDsyr2 -//clAmdBlasDsyr2k -//clAmdBlasDsyr2kEx -//clAmdBlasDsyrk -//clAmdBlasDsyrkEx -//clAmdBlasDtbmv -//clAmdBlasDtbsv -//clAmdBlasDtpmv -//clAmdBlasDtpsv -//clAmdBlasDtrmm -//clAmdBlasDtrmmEx -//clAmdBlasDtrmv -//clAmdBlasDtrsm -//clAmdBlasDtrsmEx -//clAmdBlasDtrsv -//clAmdBlasDzasum -//clAmdBlasDznrm2 -//clAmdBlasGetVersion -//clAmdBlasRemoveScratchImage -//clAmdBlasSasum -//clAmdBlasSaxpy -//clAmdBlasScasum -//clAmdBlasScnrm2 -//clAmdBlasScopy -//clAmdBlasSdot -clAmdBlasSetup -//clAmdBlasSgbmv -//clAmdBlasSgemm -clAmdBlasSgemmEx -//clAmdBlasSgemv -//clAmdBlasSgemvEx -//clAmdBlasSger -//clAmdBlasSnrm2 -//clAmdBlasSrot -//clAmdBlasSrotg -//clAmdBlasSrotm -//clAmdBlasSrotmg -//clAmdBlasSsbmv -//clAmdBlasSscal -//clAmdBlasSspmv -//clAmdBlasSspr -//clAmdBlasSspr2 -//clAmdBlasSswap -//clAmdBlasSsymm -//clAmdBlasSsymv -//clAmdBlasSsymvEx -//clAmdBlasSsyr -//clAmdBlasSsyr2 -//clAmdBlasSsyr2k -//clAmdBlasSsyr2kEx -//clAmdBlasSsyrk -//clAmdBlasSsyrkEx -//clAmdBlasStbmv -//clAmdBlasStbsv -//clAmdBlasStpmv -//clAmdBlasStpsv -//clAmdBlasStrmm -//clAmdBlasStrmmEx -//clAmdBlasStrmv -//clAmdBlasStrsm -//clAmdBlasStrsmEx -//clAmdBlasStrsv -clAmdBlasTeardown -//clAmdBlasZaxpy -//clAmdBlasZcopy -//clAmdBlasZdotc -//clAmdBlasZdotu -//clAmdBlasZdrot -//clAmdBlasZdscal -//clAmdBlasZgbmv -//clAmdBlasZgemm -clAmdBlasZgemmEx -//clAmdBlasZgemv -//clAmdBlasZgemvEx -//clAmdBlasZgerc -//clAmdBlasZgeru -//clAmdBlasZhbmv -//clAmdBlasZhemm -//clAmdBlasZhemv -//clAmdBlasZher -//clAmdBlasZher2 -//clAmdBlasZher2k -//clAmdBlasZherk -//clAmdBlasZhpmv -//clAmdBlasZhpr -//clAmdBlasZhpr2 -//clAmdBlasZrotg -//clAmdBlasZscal -//clAmdBlasZswap -//clAmdBlasZsymm -//clAmdBlasZsyr2k -//clAmdBlasZsyr2kEx -//clAmdBlasZsyrk -//clAmdBlasZsyrkEx -//clAmdBlasZtbmv -//clAmdBlasZtbsv -//clAmdBlasZtpmv -//clAmdBlasZtpsv -//clAmdBlasZtrmm -//clAmdBlasZtrmmEx -//clAmdBlasZtrmv -//clAmdBlasZtrsm -//clAmdBlasZtrsmEx -//clAmdBlasZtrsv -//clAmdBlasiCamax -//clAmdBlasiDamax -//clAmdBlasiSamax -//clAmdBlasiZamax -#total 175 diff --git a/modules/core/src/opencl/runtime/generator/filter/opencl_clamdfft_functions.list b/modules/core/src/opencl/runtime/generator/filter/opencl_clamdfft_functions.list deleted file mode 100644 index 32e9a9f344a9..000000000000 --- a/modules/core/src/opencl/runtime/generator/filter/opencl_clamdfft_functions.list +++ /dev/null @@ -1,33 +0,0 @@ -clAmdFftBakePlan -//clAmdFftCopyPlan -clAmdFftCreateDefaultPlan -clAmdFftDestroyPlan -clAmdFftEnqueueTransform -//clAmdFftGetLayout -//clAmdFftGetPlanBatchSize -//clAmdFftGetPlanContext -//clAmdFftGetPlanDim -//clAmdFftGetPlanDistance -//clAmdFftGetPlanInStride -//clAmdFftGetPlanLength -//clAmdFftGetPlanOutStride -//clAmdFftGetPlanPrecision -//clAmdFftGetPlanScale -//clAmdFftGetPlanTransposeResult -//clAmdFftGetResultLocation -clAmdFftGetTmpBufSize -clAmdFftGetVersion -clAmdFftSetLayout -clAmdFftSetPlanBatchSize -//clAmdFftSetPlanDim -clAmdFftSetPlanDistance -clAmdFftSetPlanInStride -//clAmdFftSetPlanLength -clAmdFftSetPlanOutStride -clAmdFftSetPlanPrecision -clAmdFftSetPlanScale -//clAmdFftSetPlanTransposeResult -clAmdFftSetResultLocation -clAmdFftSetup -clAmdFftTeardown -#total 32 diff --git a/modules/core/src/opencl/runtime/generator/filter/opencl_clblas_functions.list b/modules/core/src/opencl/runtime/generator/filter/opencl_clblas_functions.list new file mode 100644 index 000000000000..bbbf4c05d2e3 --- /dev/null +++ b/modules/core/src/opencl/runtime/generator/filter/opencl_clblas_functions.list @@ -0,0 +1,148 @@ +//clblasCaxpy +//clblasCcopy +//clblasCdotc +//clblasCdotu +//clblasCgbmv +clblasCgemm +//clblasCgemv +//clblasCgerc +//clblasCgeru +//clblasChbmv +//clblasChemm +//clblasChemv +//clblasCher +//clblasCher2 +//clblasCher2k +//clblasCherk +//clblasChpmv +//clblasChpr +//clblasChpr2 +//clblasCrotg +//clblasCscal +//clblasCsrot +//clblasCsscal +//clblasCswap +//clblasCsymm +//clblasCsyr2k +//clblasCsyrk +//clblasCtbmv +//clblasCtbsv +//clblasCtpmv +//clblasCtpsv +//clblasCtrmm +//clblasCtrmv +//clblasCtrsm +//clblasCtrsv +//clblasDasum +//clblasDaxpy +//clblasDcopy +//clblasDdot +//clblasDgbmv +clblasDgemm +//clblasDgemv +//clblasDger +//clblasDnrm2 +//clblasDrot +//clblasDrotg +//clblasDrotm +//clblasDrotmg +//clblasDsbmv +//clblasDscal +//clblasDspmv +//clblasDspr +//clblasDspr2 +//clblasDswap +//clblasDsymm +//clblasDsymv +//clblasDsyr +//clblasDsyr2 +//clblasDsyr2k +//clblasDsyrk +//clblasDtbmv +//clblasDtbsv +//clblasDtpmv +//clblasDtpsv +//clblasDtrmm +//clblasDtrmv +//clblasDtrsm +//clblasDtrsv +//clblasDzasum +//clblasDznrm2 +//clblasGetVersion +//clblasSasum +//clblasSaxpy +//clblasScasum +//clblasScnrm2 +//clblasScopy +//clblasSdot +clblasSetup +//clblasSgbmv +clblasSgemm +//clblasSgemv +//clblasSger +//clblasSnrm2 +//clblasSrot +//clblasSrotg +//clblasSrotm +//clblasSrotmg +//clblasSsbmv +//clblasSscal +//clblasSspmv +//clblasSspr +//clblasSspr2 +//clblasSswap +//clblasSsymm +//clblasSsymv +//clblasSsyr +//clblasSsyr2 +//clblasSsyr2k +//clblasSsyrk +//clblasStbmv +//clblasStbsv +//clblasStpmv +//clblasStpsv +//clblasStrmm +//clblasStrmv +//clblasStrsm +//clblasStrsv +clblasTeardown +//clblasZaxpy +//clblasZcopy +//clblasZdotc +//clblasZdotu +//clblasZdrot +//clblasZdscal +//clblasZgbmv +clblasZgemm +//clblasZgemv +//clblasZgerc +//clblasZgeru +//clblasZhbmv +//clblasZhemm +//clblasZhemv +//clblasZher +//clblasZher2 +//clblasZher2k +//clblasZherk +//clblasZhpmv +//clblasZhpr +//clblasZhpr2 +//clblasZrotg +//clblasZscal +//clblasZswap +//clblasZsymm +//clblasZsyr2k +//clblasZsyrk +//clblasZtbmv +//clblasZtbsv +//clblasZtpmv +//clblasZtpsv +//clblasZtrmm +//clblasZtrmv +//clblasZtrsm +//clblasZtrsv +//clblasiCamax +//clblasiDamax +//clblasiSamax +//clblasiZamax +#total 147 diff --git a/modules/core/src/opencl/runtime/generator/filter/opencl_clfft_functions.list b/modules/core/src/opencl/runtime/generator/filter/opencl_clfft_functions.list new file mode 100644 index 000000000000..45e01bf89f43 --- /dev/null +++ b/modules/core/src/opencl/runtime/generator/filter/opencl_clfft_functions.list @@ -0,0 +1,34 @@ +clfftBakePlan +//clfftCopyPlan +clfftCreateDefaultPlan +clfftDestroyPlan +clfftEnqueueTransform +//clfftGetLayout +//clfftGetPlanBatchSize +//clfftGetPlanContext +//clfftGetPlanDim +//clfftGetPlanDistance +//clfftGetPlanInStride +//clfftGetPlanLength +//clfftGetPlanOutStride +//clfftGetPlanPrecision +//clfftGetPlanScale +//clfftGetPlanTransposeResult +//clfftGetResultLocation +clfftGetTmpBufSize +clfftGetVersion +clfftSetLayout +clfftSetPlanBatchSize +//clfftSetPlanCallback +//clfftSetPlanDim +clfftSetPlanDistance +clfftSetPlanInStride +//clfftSetPlanLength +clfftSetPlanOutStride +clfftSetPlanPrecision +clfftSetPlanScale +//clfftSetPlanTransposeResult +clfftSetResultLocation +clfftSetup +clfftTeardown +#total 33 diff --git a/modules/core/src/opencl/runtime/generator/parser_cl.py b/modules/core/src/opencl/runtime/generator/parser_cl.py index 1f5050445c21..54133e808565 100644 --- a/modules/core/src/opencl/runtime/generator/parser_cl.py +++ b/modules/core/src/opencl/runtime/generator/parser_cl.py @@ -10,10 +10,10 @@ try: if len(sys.argv) > 1: module_name = sys.argv[1] - outfile = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/%s.hpp' % module_name, 'wb') - outfile_impl = open('../autogenerated/%s_impl.hpp' % module_name, 'wb') - outfile_static_impl = open('../autogenerated/%s_static_impl.hpp' % module_name, 'wb') - outfile_wrappers = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/%s_wrappers.hpp' % module_name, 'wb') + outfile = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/%s.hpp' % module_name, 'w') + outfile_impl = open('../autogenerated/%s_impl.hpp' % module_name, 'w') + outfile_static_impl = open('../autogenerated/%s_static_impl.hpp' % module_name, 'w') + outfile_wrappers = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/%s_wrappers.hpp' % module_name, 'w') if len(sys.argv) > 2: f = open(sys.argv[2], "r") else: @@ -102,7 +102,7 @@ numEnabled = readFunctionFilter(fns, filterFileName) functionsFilter = generateFilterNames(fns) -filter_file = open(filterFileName, 'wb') +filter_file = open(filterFileName, 'w') filter_file.write(functionsFilter) ctx = {} diff --git a/modules/core/src/opencl/runtime/generator/parser_clamdblas.py b/modules/core/src/opencl/runtime/generator/parser_clblas.py similarity index 84% rename from modules/core/src/opencl/runtime/generator/parser_clamdblas.py rename to modules/core/src/opencl/runtime/generator/parser_clblas.py index 0303517bd549..d01af0618db9 100644 --- a/modules/core/src/opencl/runtime/generator/parser_clamdblas.py +++ b/modules/core/src/opencl/runtime/generator/parser_clblas.py @@ -1,6 +1,6 @@ #!/bin/python # usage: -# cat clAmdBlas.h | $0 +# cat clBLAS.h | $0 from __future__ import print_function import sys, re; @@ -23,7 +23,7 @@ assert isinstance(line, str) line = line.strip() parts = line.split(); - if (line.startswith('clAmd') or line.startswith('cl_') or line == 'void') and len(line.split()) == 1 and line.find('(') == -1: + if (line.startswith('clblas') or line.startswith('cl_') or line == 'void') and len(line.split()) == 1 and line.find('(') == -1: fn = {} modifiers = [] ret = [] @@ -90,11 +90,11 @@ from common import * -filterFileName='./filter/opencl_clamdblas_functions.list' +filterFileName='./filter/opencl_clblas_functions.list' numEnabled = readFunctionFilter(fns, filterFileName) functionsFilter = generateFilterNames(fns) -filter_file = open(filterFileName, 'wb') +filter_file = open(filterFileName, 'w') filter_file.write(functionsFilter) ctx = {} @@ -102,8 +102,8 @@ ctx['CLAMDBLAS_REMAP_DYNAMIC'] = generateRemapDynamic(fns) ctx['CLAMDBLAS_FN_DECLARATIONS'] = generateFnDeclaration(fns) -sys.stdout = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp', 'wb') -ProcessTemplate('template/opencl_clamdblas.hpp.in', ctx) +sys.stdout = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/opencl_clblas.hpp', 'w') +ProcessTemplate('template/opencl_clblas.hpp.in', ctx) ctx['CL_FN_ENUMS'] = generateEnums(fns, 'OPENCLAMDBLAS_FN', ) ctx['CL_FN_SWITCH'] = generateTemplates(23, 'openclamdblas_fn', 'openclamdblas_check_fn', '') @@ -111,5 +111,5 @@ ctx['CL_FN_ENTRY_LIST'] = generateListOfDefinitions(fns, 'openclamdblas_fn') ctx['CL_NUMBER_OF_ENABLED_FUNCTIONS'] = '// number of enabled functions: %d' % (numEnabled) -sys.stdout = open('../autogenerated/opencl_clamdblas_impl.hpp', 'wb') -ProcessTemplate('template/opencl_clamdblas_impl.hpp.in', ctx) +sys.stdout = open('../autogenerated/opencl_clblas_impl.hpp', 'w') +ProcessTemplate('template/opencl_clblas_impl.hpp.in', ctx) diff --git a/modules/core/src/opencl/runtime/generator/parser_clamdfft.py b/modules/core/src/opencl/runtime/generator/parser_clfft.py similarity index 85% rename from modules/core/src/opencl/runtime/generator/parser_clamdfft.py rename to modules/core/src/opencl/runtime/generator/parser_clfft.py index e0229f1d9d57..e3daaee621dd 100644 --- a/modules/core/src/opencl/runtime/generator/parser_clamdfft.py +++ b/modules/core/src/opencl/runtime/generator/parser_clfft.py @@ -1,6 +1,6 @@ #!/bin/python # usage: -# cat clAmdFft.h | $0 +# cat clFFT.h | $0 from __future__ import print_function import sys, re; @@ -23,7 +23,7 @@ break assert isinstance(line, str) line = line.strip() - if line.startswith('CLAMDFFTAPI'): + if line.startswith('CLFFTAPI'): line = re.sub(r'\n', r'', line) while True: nl = f.readline() @@ -44,7 +44,7 @@ i = 0 while True: - if parts[i] == "CLAMDFFTAPI": + if parts[i] == "CLFFTAPI": modifiers.append(parts[i]) else: break @@ -87,11 +87,11 @@ from common import * -filterFileName='./filter/opencl_clamdfft_functions.list' +filterFileName='./filter/opencl_clfft_functions.list' numEnabled = readFunctionFilter(fns, filterFileName) functionsFilter = generateFilterNames(fns) -filter_file = open(filterFileName, 'wb') +filter_file = open(filterFileName, 'w') filter_file.write(functionsFilter) ctx = {} @@ -99,8 +99,8 @@ ctx['CLAMDFFT_REMAP_DYNAMIC'] = generateRemapDynamic(fns) ctx['CLAMDFFT_FN_DECLARATIONS'] = generateFnDeclaration(fns) -sys.stdout = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp', 'wb') -ProcessTemplate('template/opencl_clamdfft.hpp.in', ctx) +sys.stdout = open('../../../../include/opencv2/core/opencl/runtime/autogenerated/opencl_clfft.hpp', 'w') +ProcessTemplate('template/opencl_clfft.hpp.in', ctx) ctx['CL_FN_ENUMS'] = generateEnums(fns, 'OPENCLAMDFFT_FN') ctx['CL_FN_SWITCH'] = generateTemplates(23, 'openclamdfft_fn', 'openclamdfft_check_fn', '') @@ -108,5 +108,5 @@ ctx['CL_FN_ENTRY_LIST'] = generateListOfDefinitions(fns, 'openclamdfft_fn') ctx['CL_NUMBER_OF_ENABLED_FUNCTIONS'] = '// number of enabled functions: %d' % (numEnabled) -sys.stdout = open('../autogenerated/opencl_clamdfft_impl.hpp', 'wb') -ProcessTemplate('template/opencl_clamdfft_impl.hpp.in', ctx) +sys.stdout = open('../autogenerated/opencl_clfft_impl.hpp', 'w') +ProcessTemplate('template/opencl_clfft_impl.hpp.in', ctx) diff --git a/modules/core/src/opencl/runtime/generator/template/opencl_clamdblas.hpp.in b/modules/core/src/opencl/runtime/generator/template/opencl_clblas.hpp.in similarity index 87% rename from modules/core/src/opencl/runtime/generator/template/opencl_clamdblas.hpp.in rename to modules/core/src/opencl/runtime/generator/template/opencl_clblas.hpp.in index 5b48f5140048..7c19bfd51283 100644 --- a/modules/core/src/opencl/runtime/generator/template/opencl_clamdblas.hpp.in +++ b/modules/core/src/opencl/runtime/generator/template/opencl_clblas.hpp.in @@ -4,7 +4,7 @@ @CLAMDBLAS_REMAP_ORIGIN@ -#include +#include @CLAMDBLAS_REMAP_DYNAMIC@ diff --git a/modules/core/src/opencl/runtime/generator/template/opencl_clamdblas_impl.hpp.in b/modules/core/src/opencl/runtime/generator/template/opencl_clblas_impl.hpp.in similarity index 100% rename from modules/core/src/opencl/runtime/generator/template/opencl_clamdblas_impl.hpp.in rename to modules/core/src/opencl/runtime/generator/template/opencl_clblas_impl.hpp.in diff --git a/modules/core/src/opencl/runtime/generator/template/opencl_clamdfft.hpp.in b/modules/core/src/opencl/runtime/generator/template/opencl_clfft.hpp.in similarity index 87% rename from modules/core/src/opencl/runtime/generator/template/opencl_clamdfft.hpp.in rename to modules/core/src/opencl/runtime/generator/template/opencl_clfft.hpp.in index 4e8a5635177c..f03c4b2db06a 100644 --- a/modules/core/src/opencl/runtime/generator/template/opencl_clamdfft.hpp.in +++ b/modules/core/src/opencl/runtime/generator/template/opencl_clfft.hpp.in @@ -4,7 +4,7 @@ @CLAMDFFT_REMAP_ORIGIN@ -#include +#include @CLAMDFFT_REMAP_DYNAMIC@ diff --git a/modules/core/src/opencl/runtime/generator/template/opencl_clamdfft_impl.hpp.in b/modules/core/src/opencl/runtime/generator/template/opencl_clfft_impl.hpp.in similarity index 100% rename from modules/core/src/opencl/runtime/generator/template/opencl_clamdfft_impl.hpp.in rename to modules/core/src/opencl/runtime/generator/template/opencl_clfft_impl.hpp.in diff --git a/modules/core/src/opencl/runtime/opencl_clamdblas.cpp b/modules/core/src/opencl/runtime/opencl_clblas.cpp similarity index 92% rename from modules/core/src/opencl/runtime/opencl_clamdblas.cpp rename to modules/core/src/opencl/runtime/opencl_clblas.cpp index 379929993f49..419c4df443cf 100644 --- a/modules/core/src/opencl/runtime/opencl_clamdblas.cpp +++ b/modules/core/src/opencl/runtime/opencl_clblas.cpp @@ -44,7 +44,7 @@ #ifdef HAVE_CLAMDBLAS #include "opencv2/core/opencl/runtime/opencl_core.hpp" -#include "opencv2/core/opencl/runtime/opencl_clamdblas.hpp" +#include "opencv2/core/opencl/runtime/opencl_clblas.hpp" #if defined(_WIN32) #include @@ -54,10 +54,10 @@ static HMODULE opencl_module = NULL; if (!opencl_module) { - opencl_module = GetModuleHandleA("clAmdBlas.dll"); + opencl_module = GetModuleHandleA("clBLAS.dll"); if (!opencl_module) { - opencl_module = LoadLibraryA("clAmdBlas.dll"); + opencl_module = LoadLibraryA("clBLAS.dll"); if (!opencl_module) return NULL; } @@ -76,7 +76,7 @@ static void* h = NULL; if (!h) { - h = dlopen("libclAmdBlas.so", RTLD_LAZY | RTLD_GLOBAL); + h = dlopen("libclBLAS.so", RTLD_LAZY | RTLD_GLOBAL); if (!h) return NULL; } @@ -109,7 +109,7 @@ static void* openclamdblas_check_fn(int ID); // END OF CUSTOM FUNCTIONS HERE // -#include "autogenerated/opencl_clamdblas_impl.hpp" +#include "autogenerated/opencl_clblas_impl.hpp" static void* openclamdblas_check_fn(int ID) { diff --git a/modules/core/src/opencl/runtime/opencl_clamdfft.cpp b/modules/core/src/opencl/runtime/opencl_clfft.cpp similarity index 92% rename from modules/core/src/opencl/runtime/opencl_clamdfft.cpp rename to modules/core/src/opencl/runtime/opencl_clfft.cpp index 255bcd826a12..44e7466f96b0 100644 --- a/modules/core/src/opencl/runtime/opencl_clamdfft.cpp +++ b/modules/core/src/opencl/runtime/opencl_clfft.cpp @@ -44,7 +44,7 @@ #ifdef HAVE_CLAMDFFT #include "opencv2/core/opencl/runtime/opencl_core.hpp" -#include "opencv2/core/opencl/runtime/opencl_clamdfft.hpp" +#include "opencv2/core/opencl/runtime/opencl_clfft.hpp" #if defined(_WIN32) #include @@ -54,10 +54,10 @@ static HMODULE opencl_module = NULL; if (!opencl_module) { - opencl_module = GetModuleHandleA("clAmdFft.Runtime.dll"); + opencl_module = GetModuleHandleA("clFFT.dll"); if (!opencl_module) { - opencl_module = LoadLibraryA("clAmdFft.Runtime.dll"); + opencl_module = LoadLibraryA("clFFT.dll"); if (!opencl_module) return NULL; } @@ -76,7 +76,7 @@ static void* h = NULL; if (!h) { - h = dlopen("libclAmdFft.Runtime.so", RTLD_LAZY | RTLD_GLOBAL); + h = dlopen("libclFFT.so", RTLD_LAZY | RTLD_GLOBAL); if (!h) return NULL; } @@ -109,7 +109,7 @@ static void* openclamdfft_check_fn(int ID); // END OF CUSTOM FUNCTIONS HERE // -#include "autogenerated/opencl_clamdfft_impl.hpp" +#include "autogenerated/opencl_clfft_impl.hpp" static void* openclamdfft_check_fn(int ID) { diff --git a/modules/core/src/parallel.cpp b/modules/core/src/parallel.cpp index 7bb7e4633dcd..81ddd0c5ddce 100644 --- a/modules/core/src/parallel.cpp +++ b/modules/core/src/parallel.cpp @@ -72,7 +72,7 @@ #endif #endif -#if defined CV_CXX11 +#ifndef OPENCV_DISABLE_THREAD_SUPPORT #include #endif @@ -884,6 +884,7 @@ T minNonZero(const T& val_1, const T& val_2) return (val_1 != 0) ? val_1 : val_2; } +#ifndef OPENCV_DISABLE_THREAD_SUPPORT static int getNumberOfCPUs_() { @@ -986,6 +987,13 @@ int getNumberOfCPUs() return nCPUs; // cached value } +#else // OPENCV_DISABLE_THREAD_SUPPORT +int getNumberOfCPUs() +{ + return 1; +} +#endif // OPENCV_DISABLE_THREAD_SUPPORT + const char* currentParallelFramework() { std::shared_ptr& api = getCurrentParallelForAPI(); diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 4bf52a3134df..32328361e874 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -143,17 +143,17 @@ static const char symbols[9] = "ucwsifdh"; static char typeSymbol(int depth) { CV_StaticAssert(CV_64F == 6, ""); - CV_Assert(depth >=0 && depth <= CV_64F); + CV_CheckDepth(depth, depth >=0 && depth <= CV_16F, ""); return symbols[depth]; } static int symbolToType(char c) { + if (c == 'r') + return CV_SEQ_ELTYPE_PTR; const char* pos = strchr( symbols, c ); if( !pos ) CV_Error( CV_StsBadArg, "Invalid data type specification" ); - if (c == 'r') - return CV_SEQ_ELTYPE_PTR; return static_cast(pos - symbols); } @@ -245,8 +245,12 @@ int calcStructSize( const char* dt, int initial_size ) { int size = calcElemSize( dt, initial_size ); size_t elem_max_size = 0; - for ( const char * type = dt; *type != '\0'; type++ ) { - switch ( *type ) + for ( const char * type = dt; *type != '\0'; type++ ) + { + char v = *type; + if (v >= '0' && v <= '9') + continue; // skip vector size + switch (v) { case 'u': { elem_max_size = std::max( elem_max_size, sizeof(uchar ) ); break; } case 'c': { elem_max_size = std::max( elem_max_size, sizeof(schar ) ); break; } @@ -255,7 +259,9 @@ int calcStructSize( const char* dt, int initial_size ) case 'i': { elem_max_size = std::max( elem_max_size, sizeof(int ) ); break; } case 'f': { elem_max_size = std::max( elem_max_size, sizeof(float ) ); break; } case 'd': { elem_max_size = std::max( elem_max_size, sizeof(double) ); break; } - default: break; + case 'h': { elem_max_size = std::max(elem_max_size, sizeof(float16_t)); break; } + default: + CV_Error_(Error::StsNotImplemented, ("Unknown type identifier: '%c' in '%s'", (char)(*type), dt)); } } size = cvAlign( size, static_cast(elem_max_size) ); @@ -1054,6 +1060,7 @@ class FileStorage::Impl : public FileStorage_API CV_Assert(write_mode); size_t elemSize = fs::calcStructSize(dt.c_str(), 0); + CV_Assert(elemSize); CV_Assert( len % elemSize == 0 ); len /= elemSize; diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index c68ca458b710..777efceca021 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -216,7 +216,9 @@ std::wstring GetTempFileNameWinRT(std::wstring prefix) #endif #else +#ifndef OPENCV_DISABLE_THREAD_SUPPORT #include +#endif #include #include @@ -395,6 +397,7 @@ struct HWFeatures g_hwFeatureNames[CPU_VSX3] = "VSX3"; g_hwFeatureNames[CPU_MSA] = "CPU_MSA"; + g_hwFeatureNames[CPU_RISCVV] = "RISCVV"; g_hwFeatureNames[CPU_AVX512_COMMON] = "AVX512-COMMON"; g_hwFeatureNames[CPU_AVX512_SKX] = "AVX512-SKX"; @@ -590,6 +593,9 @@ struct HWFeatures #if defined _ARM_ && (defined(_WIN32_WCE) && _WIN32_WCE >= 0x800) have[CV_CPU_NEON] = true; #endif + #ifdef __riscv_vector + have[CV_CPU_RISCVV] = true; + #endif #ifdef __mips_msa have[CV_CPU_MSA] = true; #endif @@ -1362,6 +1368,8 @@ bool __termination = false; namespace details { +#ifndef OPENCV_DISABLE_THREAD_SUPPORT + #ifdef _WIN32 #ifdef _MSC_VER #pragma warning(disable:4505) // unreferenced local function has been removed @@ -1774,14 +1782,122 @@ static void WINAPI opencv_fls_destructor(void* pData) #endif // CV_USE_FLS #endif // _WIN32 +#else // OPENCV_DISABLE_THREAD_SUPPORT + +// no threading (OPENCV_DISABLE_THREAD_SUPPORT=ON) +class TlsStorage +{ +public: + TlsStorage() + { + slots.reserve(32); + } + ~TlsStorage() + { + for (size_t slotIdx = 0; slotIdx < slots.size(); slotIdx++) + { + SlotInfo& s = slots[slotIdx]; + TLSDataContainer* container = s.container; + if (container && s.data) + { + container->deleteDataInstance(s.data); // Can't use from SlotInfo destructor + s.data = nullptr; + } + } + } + + // Reserve TLS storage index + size_t reserveSlot(TLSDataContainer* container) + { + size_t slotsSize = slots.size(); + for (size_t slot = 0; slot < slotsSize; slot++) + { + SlotInfo& s = slots[slot]; + if (s.container == NULL) + { + CV_Assert(!s.data); + s.container = container; + return slot; + } + } + + // create new slot + slots.push_back(SlotInfo(container)); + return slotsSize; + } + + // Release TLS storage index and pass associated data to caller + void releaseSlot(size_t slotIdx, std::vector &dataVec, bool keepSlot = false) + { + CV_Assert(slotIdx < slots.size()); + SlotInfo& s = slots[slotIdx]; + void* data = s.data; + if (data) + { + dataVec.push_back(data); + s.data = nullptr; + } + if (!keepSlot) + { + s.container = NULL; // mark slot as free (see reserveSlot() implementation) + } + } + + // Get data by TLS storage index + void* getData(size_t slotIdx) const + { + CV_Assert(slotIdx < slots.size()); + const SlotInfo& s = slots[slotIdx]; + return s.data; + } + + // Gather data from threads by TLS storage index + void gather(size_t slotIdx, std::vector &dataVec) + { + CV_Assert(slotIdx < slots.size()); + SlotInfo& s = slots[slotIdx]; + void* data = s.data; + if (data) + dataVec.push_back(data); + return; + } + + // Set data to storage index + void setData(size_t slotIdx, void* pData) + { + CV_Assert(slotIdx < slots.size()); + SlotInfo& s = slots[slotIdx]; + s.data = pData; + } + +private: + struct SlotInfo + { + SlotInfo(TLSDataContainer* _container) : container(_container), data(nullptr) {} + TLSDataContainer* container; // attached container (to dispose data) + void* data; + }; + std::vector slots; +}; + +static TlsStorage& getTlsStorage() +{ + static TlsStorage g_storage; // no threading + return g_storage; +} + +#endif // OPENCV_DISABLE_THREAD_SUPPORT + } // namespace details using namespace details; void releaseTlsStorageThread() { +#ifndef OPENCV_DISABLE_THREAD_SUPPORT if (!g_isTlsStorageInitialized) return; // nothing to release, so prefer to avoid creation of new global structures getTlsStorage().releaseThread(); +#endif } TLSDataContainer::TLSDataContainer() @@ -1831,7 +1947,15 @@ void* TLSDataContainer::getData() const { // Create new data instance and save it to TLS storage pData = createDataInstance(); - getTlsStorage().setData(key_, pData); + try + { + getTlsStorage().setData(key_, pData); + } + catch (...) + { + deleteDataInstance(pData); + throw; + } } return pData; } diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp index 09ba92ecdee7..bbb34a725604 100644 --- a/modules/core/src/umatrix.cpp +++ b/modules/core/src/umatrix.cpp @@ -56,10 +56,6 @@ void setSize(UMat& m, int _dims, const int* _sz, const size_t* _steps, void updateContinuityFlag(UMat& m); void finalizeHdr(UMat& m); -// it should be a prime number for the best hash function -enum { UMAT_NLOCKS = 31 }; -static Mutex umatLocks[UMAT_NLOCKS]; - UMatData::UMatData(const MatAllocator* allocator) { prevAllocator = currAllocator = allocator; @@ -131,6 +127,12 @@ UMatData::~UMatData() } } +#ifndef OPENCV_DISABLE_THREAD_SUPPORT + +// it should be a prime number for the best hash function +enum { UMAT_NLOCKS = 31 }; +static Mutex umatLocks[UMAT_NLOCKS]; + static size_t getUMatDataLockIndex(const UMatData* u) { size_t idx = ((size_t)(void*)u) % UMAT_NLOCKS; @@ -228,6 +230,33 @@ UMatDataAutoLock::~UMatDataAutoLock() getUMatDataAutoLocker().release(u1, u2); } +#else + +void UMatData::lock() +{ + // nothing in OPENCV_DISABLE_THREAD_SUPPORT mode +} + +void UMatData::unlock() +{ + // nothing in OPENCV_DISABLE_THREAD_SUPPORT mode +} + +UMatDataAutoLock::UMatDataAutoLock(UMatData* u) : u1(u), u2(NULL) +{ + // nothing in OPENCV_DISABLE_THREAD_SUPPORT mode +} +UMatDataAutoLock::UMatDataAutoLock(UMatData* u1_, UMatData* u2_) : u1(u1_), u2(u2_) +{ + // nothing in OPENCV_DISABLE_THREAD_SUPPORT mode +} +UMatDataAutoLock::~UMatDataAutoLock() +{ + // nothing in OPENCV_DISABLE_THREAD_SUPPORT mode +} + +#endif // OPENCV_DISABLE_THREAD_SUPPORT + //////////////////////////////// UMat //////////////////////////////// UMat::UMat(UMatUsageFlags _usageFlags) CV_NOEXCEPT @@ -307,8 +336,7 @@ UMat& UMat::operator=(const UMat& m) else copySize(m); allocator = m.allocator; - if (usageFlags == USAGE_DEFAULT) - usageFlags = m.usageFlags; + usageFlags = m.usageFlags; u = m.u; offset = m.offset; } @@ -332,9 +360,6 @@ void UMat::assignTo(UMat& m, int _type) const void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags) { - _type &= TYPE_MASK; - if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u ) - return; int sz[] = {_rows, _cols}; create(2, sz, _type, _usageFlags); } @@ -426,7 +451,9 @@ UMat& UMat::operator=(UMat&& m) m.step.p = m.step.buf; m.size.p = &m.rows; } - m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0; + m.flags = MAGIC_VAL; + m.usageFlags = USAGE_DEFAULT; + m.dims = m.rows = m.cols = 0; m.allocator = NULL; m.u = NULL; m.offset = 0; @@ -600,6 +627,7 @@ UMat Mat::getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags) const CV_XADD(&(u->urefcount), 1); } hdr.flags = flags; + hdr.usageFlags = usageFlags; setSize(hdr, dims, size.p, step.p); finalizeHdr(hdr); hdr.u = new_u; @@ -610,16 +638,21 @@ UMat Mat::getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags) const void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlags) { - this->usageFlags = _usageFlags; - int i; CV_Assert(0 <= d && d <= CV_MAX_DIM && _sizes); _type = CV_MAT_TYPE(_type); - if( u && (d == dims || (d == 1 && dims <= 2)) && _type == type() ) + // if param value is USAGE_DEFAULT by implicit default param value -or- explicit value + // ...then don't change the existing usageFlags + // it is not possible to change usage from non-default to USAGE_DEFAULT through create() + // ...instead must construct UMat() + if (_usageFlags == cv::USAGE_DEFAULT) + { + _usageFlags = usageFlags; + } + + if( u && (d == dims || (d == 1 && dims <= 2)) && _type == type() && _usageFlags == usageFlags ) { - if( d == 2 && rows == _sizes[0] && cols == _sizes[1] ) - return; for( i = 0; i < d; i++ ) if( size[i] != _sizes[i] ) break; @@ -636,6 +669,7 @@ void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlag } release(); + usageFlags = _usageFlags; if( d == 0 ) return; flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL; @@ -946,11 +980,11 @@ UMat UMat::reshape(int new_cn, int new_rows) const return hdr; } -UMat UMat::diag(const UMat& d) +UMat UMat::diag(const UMat& d, UMatUsageFlags usageFlags) { CV_Assert( d.cols == 1 || d.rows == 1 ); int len = d.rows + d.cols - 1; - UMat m(len, len, d.type(), Scalar(0)); + UMat m(len, len, d.type(), Scalar(0), usageFlags); UMat md = m.diag(); if( d.cols == 1 ) d.copyTo(md); @@ -1318,34 +1352,34 @@ UMat UMat::t() const return m; } -UMat UMat::zeros(int rows, int cols, int type) +UMat UMat::zeros(int rows, int cols, int type, UMatUsageFlags usageFlags) { - return UMat(rows, cols, type, Scalar::all(0)); + return UMat(rows, cols, type, Scalar::all(0), usageFlags); } -UMat UMat::zeros(Size size, int type) +UMat UMat::zeros(Size size, int type, UMatUsageFlags usageFlags) { - return UMat(size, type, Scalar::all(0)); + return UMat(size, type, Scalar::all(0), usageFlags); } -UMat UMat::zeros(int ndims, const int* sz, int type) +UMat UMat::zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags) { - return UMat(ndims, sz, type, Scalar::all(0)); + return UMat(ndims, sz, type, Scalar::all(0), usageFlags); } -UMat UMat::ones(int rows, int cols, int type) +UMat UMat::ones(int rows, int cols, int type, UMatUsageFlags usageFlags) { - return UMat::ones(Size(cols, rows), type); + return UMat(rows, cols, type, Scalar(1), usageFlags); } -UMat UMat::ones(Size size, int type) +UMat UMat::ones(Size size, int type, UMatUsageFlags usageFlags) { - return UMat(size, type, Scalar(1)); + return UMat(size, type, Scalar(1), usageFlags); } -UMat UMat::ones(int ndims, const int* sz, int type) +UMat UMat::ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags) { - return UMat(ndims, sz, type, Scalar(1)); + return UMat(ndims, sz, type, Scalar(1), usageFlags); } } diff --git a/modules/core/src/utils/logtagmanager.hpp b/modules/core/src/utils/logtagmanager.hpp index 29a1776ada21..ab4bb9b7d3d4 100644 --- a/modules/core/src/utils/logtagmanager.hpp +++ b/modules/core/src/utils/logtagmanager.hpp @@ -37,8 +37,8 @@ class LogTagManager // also, extensible functions (accepting user-provided callback) are not allowed // to call LogTagManger (to prevent iterator invalidation), which needs enforced // with a non-recursive mutex. - using MutexType = std::mutex; - using LockType = std::lock_guard; + using MutexType = cv::Mutex; + using LockType = cv::AutoLock; enum class MatchingScope { diff --git a/modules/core/test/ocl/test_matrix_expr.cpp b/modules/core/test/ocl/test_matrix_expr.cpp index 7a5ff72cb24e..f11c0a6ebb6d 100644 --- a/modules/core/test/ocl/test_matrix_expr.cpp +++ b/modules/core/test/ocl/test_matrix_expr.cpp @@ -76,6 +76,24 @@ OCL_TEST_P(UMatExpr, Ones) } } +//////////////////////////////// with usageFlags ///////////////////////////////////////////////// + +OCL_TEST_P(UMatExpr, WithUsageFlags) +{ + for (int j = 0; j < test_loop_times; j++) + { + generateTestData(); + + UMat u0 = UMat::zeros(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY); + UMat u1 = UMat::ones(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY); + UMat u8 = UMat::eye(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY); + + EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u0.usageFlags); + EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u1.usageFlags); + EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u8.usageFlags); + } +} + //////////////////////////////// Instantiation ///////////////////////////////////////////////// OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, UMatExpr, Combine(OCL_ALL_DEPTHS_16F, OCL_ALL_CHANNELS)); diff --git a/modules/core/test/ocl/test_opencl.cpp b/modules/core/test/ocl/test_opencl.cpp index e639f729485e..daa023534d14 100644 --- a/modules/core/test/ocl/test_opencl.cpp +++ b/modules/core/test/ocl/test_opencl.cpp @@ -132,6 +132,73 @@ TEST(OpenCL, support_SPIR_programs) testOpenCLKernel(k); } + +TEST(OpenCL, image2Dcount_regression_19334) +{ + cv::ocl::Context ctx = cv::ocl::Context::getDefault(); + if (!ctx.ptr()) + { + throw cvtest::SkipTestException("OpenCL is not available"); + } + cv::ocl::Device device = cv::ocl::Device::getDefault(); + if (!device.compilerAvailable()) + { + throw cvtest::SkipTestException("OpenCL compiler is not available"); + } + + std::string module_name; // empty to disable OpenCL cache + + static const char* opencl_kernel_src = +"__kernel void test_kernel(int a,\n" +" __global const uchar* src0, int src0_step, int src0_offset, int src0_rows, int src0_cols,\n" +" __global const uchar* src1, int src1_step, int src1_offset, int src1_rows, int src1_cols,\n" +" __global const uchar* src2, int src2_step, int src2_offset, int src2_rows, int src2_cols,\n" +" __read_only image2d_t image)\n" +"{\n" +"}"; + cv::ocl::ProgramSource src(module_name, "test_opencl_image_arg", opencl_kernel_src, ""); + cv::String errmsg; + cv::ocl::Program program(src, "", errmsg); + ASSERT_TRUE(program.ptr() != NULL); + cv::ocl::Kernel k("test_kernel", program); + ASSERT_FALSE(k.empty()); + + std::vector images(4); + for (size_t i = 0; i < images.size(); ++i) + images[i] = UMat(10, 10, CV_8UC1); + cv::ocl::Image2D image; + try + { + cv::ocl::Image2D image_(images.back()); + image = image_; + } + catch (const cv::Exception&) + { + throw cvtest::SkipTestException("OpenCL images are not supported"); + } + + int nargs = 0; + int a = 0; + nargs = k.set(nargs, a); + ASSERT_EQ(1, nargs); + nargs = k.set(nargs, images[0]); + ASSERT_EQ(6, nargs); + nargs = k.set(nargs, images[1]); + ASSERT_EQ(11, nargs); + nargs = k.set(nargs, images[2]); + ASSERT_EQ(16, nargs); + + // do not throw (issue of #19334) + ASSERT_NO_THROW(nargs = k.set(nargs, image)); + ASSERT_EQ(17, nargs); + + // allow to replace image argument if kernel is not running + UMat image2(10, 10, CV_8UC1); + ASSERT_NO_THROW(nargs = k.set(16, cv::ocl::Image2D(image2))); + ASSERT_EQ(17, nargs); +} + + TEST(OpenCL, move_construct_assign) { cv::ocl::Context ctx1 = cv::ocl::Context::getDefault(); diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index effb0e68e05b..9e8e242d604a 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -2166,6 +2166,15 @@ TEST(Core_Norm, IPP_regression_NORM_L1_16UC3_small) EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask)); } +TEST(Core_Norm, NORM_L2_8UC4) +{ + // Tests there is no integer overflow in norm computation for multiple channels. + const int kSide = 100; + cv::Mat4b a(kSide, kSide, cv::Scalar(255, 255, 255, 255)); + cv::Mat4b b = cv::Mat4b::zeros(kSide, kSide); + const double kNorm = 2.*kSide*255.; + EXPECT_EQ(kNorm, cv::norm(a, b, NORM_L2)); +} TEST(Core_ConvertTo, regression_12121) { diff --git a/modules/core/test/test_async.cpp b/modules/core/test/test_async.cpp index f898a22878d2..58bcfddcd769 100644 --- a/modules/core/test/test_async.cpp +++ b/modules/core/test/test_async.cpp @@ -7,7 +7,7 @@ #include -#ifdef CV_CXX11 +#if defined(CV_CXX11) && !defined(OPENCV_DISABLE_THREAD_SUPPORT) #include #include #endif @@ -85,7 +85,8 @@ TEST(Core_Async, LikePythonTest) } -#ifdef CV_CXX11 +#if defined(CV_CXX11) && !defined(OPENCV_DISABLE_THREAD_SUPPORT) + TEST(Core_Async, AsyncThread_Simple) { Mat m(3, 3, CV_32FC1, Scalar::all(5.0f)); diff --git a/modules/core/test/test_intrin_utils.hpp b/modules/core/test/test_intrin_utils.hpp index 269ebe0f2a40..5c22caaf12e5 100644 --- a/modules/core/test/test_intrin_utils.hpp +++ b/modules/core/test/test_intrin_utils.hpp @@ -577,6 +577,25 @@ template struct TheTest return *this; } + TheTest & test_mul_hi() + { + // typedef typename V_RegTraits::w_reg Rx2; + Data dataA, dataB(32767); + R a = dataA, b = dataB; + + R c = v_mul_hi(a, b); + + Data resC = c; + const int n = R::nlanes / 2; + for (int i = 0; i < n; ++i) + { + SCOPED_TRACE(cv::format("i=%d", i)); + EXPECT_EQ((typename R::lane_type)((dataA[i] * dataB[i]) >> 16), resC[i]); + } + + return *this; + } + TheTest & test_abs() { typedef typename V_RegTraits::u_reg Ru; @@ -1663,6 +1682,7 @@ void test_hal_intrin_uint16() .test_arithm_wrap() .test_mul() .test_mul_expand() + .test_mul_hi() .test_cmp() .test_shift<1>() .test_shift<8>() @@ -1697,6 +1717,7 @@ void test_hal_intrin_int16() .test_arithm_wrap() .test_mul() .test_mul_expand() + .test_mul_hi() .test_cmp() .test_shift<1>() .test_shift<8>() diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index d30c48536888..82bd05372da7 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -1837,4 +1837,69 @@ TEST(Core_InputOutput, FileStorage_copy_constructor_17412_heap) EXPECT_EQ(0, remove(fname.c_str())); } + +static void test_20279(FileStorage& fs) +{ + Mat m32fc1(5, 10, CV_32FC1, Scalar::all(0)); + for (size_t i = 0; i < m32fc1.total(); i++) + { + float v = (float)i; + m32fc1.at((int)i) = v * 0.5f; + } + Mat m16fc1; + // produces CV_16S output: convertFp16(m32fc1, m16fc1); + m32fc1.convertTo(m16fc1, CV_16FC1); + EXPECT_EQ(CV_16FC1, m16fc1.type()) << typeToString(m16fc1.type()); + //std::cout << m16fc1 << std::endl; + + Mat m32fc3(4, 3, CV_32FC3, Scalar::all(0)); + for (size_t i = 0; i < m32fc3.total(); i++) + { + float v = (float)i; + m32fc3.at((int)i) = Vec3f(v, v * 0.2f, -v); + } + Mat m16fc3; + m32fc3.convertTo(m16fc3, CV_16FC3); + EXPECT_EQ(CV_16FC3, m16fc3.type()) << typeToString(m16fc3.type()); + //std::cout << m16fc3 << std::endl; + + fs << "m16fc1" << m16fc1; + fs << "m16fc3" << m16fc3; + + string content = fs.releaseAndGetString(); + if (cvtest::debugLevel > 0) std::cout << content << std::endl; + + FileStorage fs_read(content, FileStorage::READ + FileStorage::MEMORY); + Mat m16fc1_result; + Mat m16fc3_result; + fs_read["m16fc1"] >> m16fc1_result; + ASSERT_FALSE(m16fc1_result.empty()); + EXPECT_EQ(CV_16FC1, m16fc1_result.type()) << typeToString(m16fc1_result.type()); + EXPECT_LE(cvtest::norm(m16fc1_result, m16fc1, NORM_INF), 1e-2); + + fs_read["m16fc3"] >> m16fc3_result; + ASSERT_FALSE(m16fc3_result.empty()); + EXPECT_EQ(CV_16FC3, m16fc3_result.type()) << typeToString(m16fc3_result.type()); + EXPECT_LE(cvtest::norm(m16fc3_result, m16fc3, NORM_INF), 1e-2); +} + +TEST(Core_InputOutput, FileStorage_16F_xml) +{ + FileStorage fs("test.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY); + test_20279(fs); +} + +TEST(Core_InputOutput, FileStorage_16F_yml) +{ + FileStorage fs("test.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY); + test_20279(fs); +} + +TEST(Core_InputOutput, FileStorage_16F_json) +{ + FileStorage fs("test.json", cv::FileStorage::WRITE | cv::FileStorage::MEMORY); + test_20279(fs); +} + + }} // namespace diff --git a/modules/core/test/test_opencl.cpp b/modules/core/test/test_opencl.cpp index 17cd7b5c8922..ff1391016e54 100644 --- a/modules/core/test/test_opencl.cpp +++ b/modules/core/test/test_opencl.cpp @@ -207,9 +207,32 @@ TEST_P(OCL_OpenCLExecutionContext_P, ScopeTest) executeUMatCall(); } +INSTANTIATE_TEST_CASE_P(/*nothing*/, OCL_OpenCLExecutionContext_P, getOpenCLTestConfigurations()); -INSTANTIATE_TEST_CASE_P(/*nothing*/, OCL_OpenCLExecutionContext_P, getOpenCLTestConfigurations()); +typedef testing::TestWithParam UsageFlagsFixture; +OCL_TEST_P(UsageFlagsFixture, UsageFlagsRetained) +{ + if (!cv::ocl::useOpenCL()) + { + throw SkipTestException("OpenCL is not available / disabled"); + } + + const UMatUsageFlags usage = GetParam(); + cv::UMat flip_in(10, 10, CV_32F, usage); + cv::UMat flip_out(usage); + cv::flip(flip_in, flip_out, 1); + cv::ocl::finish(); + + ASSERT_EQ(usage, flip_in.usageFlags); + ASSERT_EQ(usage, flip_out.usageFlags); +} + +INSTANTIATE_TEST_CASE_P( + /*nothing*/, + UsageFlagsFixture, + testing::Values(USAGE_DEFAULT, USAGE_ALLOCATE_HOST_MEMORY, USAGE_ALLOCATE_DEVICE_MEMORY) +); } } // namespace opencv_test::ocl diff --git a/modules/core/test/test_utils.cpp b/modules/core/test/test_utils.cpp index ed5f34603de5..c31ca75667e9 100644 --- a/modules/core/test/test_utils.cpp +++ b/modules/core/test/test_utils.cpp @@ -8,9 +8,12 @@ #include "opencv2/core/utils/logger.hpp" #include "opencv2/core/utils/buffer_area.private.hpp" -#include "test_utils_tls.impl.hpp" #include "opencv2/core/utils/filesystem.private.hpp" +#ifndef OPENCV_DISABLE_THREAD_SUPPORT +#include "test_utils_tls.impl.hpp" +#endif + namespace opencv_test { namespace { static const char * const keys = diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index 0743de00ab7f..255b41de88a5 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -738,9 +738,11 @@ CV__DNN_INLINE_NS_BEGIN CV_WRAP void enableFusion(bool fusion); /** @brief Returns overall time for inference and timings (in ticks) for layers. + * * Indexes in returned vector correspond to layers ids. Some layers can be fused with others, - * in this case zero ticks count will be return for that skipped layers. - * @param timings vector for tick timings for all layers. + * in this case zero ticks count will be return for that skipped layers. Supported by DNN_BACKEND_OPENCV on DNN_TARGET_CPU only. + * + * @param[out] timings vector for tick timings for all layers. * @return overall ticks for model inference. */ CV_WRAP int64 getPerfProfile(CV_OUT std::vector& timings); diff --git a/modules/dnn/include/opencv2/dnn/version.hpp b/modules/dnn/include/opencv2/dnn/version.hpp index 43191b89837a..0efc9c023765 100644 --- a/modules/dnn/include/opencv2/dnn/version.hpp +++ b/modules/dnn/include/opencv2/dnn/version.hpp @@ -6,7 +6,7 @@ #define OPENCV_DNN_VERSION_HPP /// Use with major OpenCV version only. -#define OPENCV_DNN_API_VERSION 20210301 +#define OPENCV_DNN_API_VERSION 20210608 #if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS #define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION) diff --git a/modules/dnn/misc/java/gen_dict.json b/modules/dnn/misc/java/gen_dict.json index 5a397eac51c0..65ecfdc25ea7 100644 --- a/modules/dnn/misc/java/gen_dict.json +++ b/modules/dnn/misc/java/gen_dict.json @@ -54,7 +54,7 @@ ] ], - "jni_name": "(*(cv::dnn::DictValue*)%(n)s_nativeObj)", + "jni_name": "(*(*(Ptr*)%(n)s_nativeObj))", "jni_type": "jlong", "suffix": "J", "j_import": "org.opencv.dnn.DictValue" diff --git a/modules/dnn/src/cuda4dnn/csl/cublas.hpp b/modules/dnn/src/cuda4dnn/csl/cublas.hpp index 2928cda7799d..760e3824fdbe 100644 --- a/modules/dnn/src/cuda4dnn/csl/cublas.hpp +++ b/modules/dnn/src/cuda4dnn/csl/cublas.hpp @@ -247,6 +247,122 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { namespace cu ); } + /** @brief Strided batched GEMM for colummn-major matrices + * + * \f$ C_i = \alpha A_i B_i + \beta C_i \f$ for a stack of matrices A, B and C indexed by i + * + * @tparam T matrix element type (must be `half` or `float`) + * + * @param handle valid cuBLAS Handle + * @param transa use transposed matrix of A_i for computation + * @param transb use transposed matrix of B_i for computation + * @param rows_c number of rows in C_i + * @param cols_c number of columns in C_i + * @param common_dim common dimension of A_i (or trans A_i) and B_i (or trans B_i) + * @param alpha scale factor for A_i B_i + * @param[in] A pointer to stack of column-major matrices A in device memory + * @param lda leading dimension of matrix A_i + * @param strideA stride between matrices in A + * @param[in] B pointer to stack of column-major matrices B in device memory + * @param ldb leading dimension of matrix B_i + * @param strideB stride between matrices in B + * @param beta scale factor for C_i + * @param[in,out] C pointer to stack of column-major matrices C in device memory + * @param ldc leading dimension of matrix C_i + * @param strideC stride between matrices in C + * @param batchCount number of matrices in the batch + * + * Exception Guarantee: Basic + */ + template + void gemmStridedBatched(const Handle& handle, + bool transa, bool transb, + std::size_t rows_c, std::size_t cols_c, std::size_t common_dim, + T alpha, const DevicePtr A, std::size_t lda, std::size_t strideA, + const DevicePtr B, std::size_t ldb, std::size_t strideB, + T beta, const DevicePtr C, std::size_t ldc, std::size_t strideC, + std::size_t batchCount); + + template <> inline + void gemmStridedBatched(const Handle& handle, + bool transa, bool transb, + std::size_t rows_c, std::size_t cols_c, std::size_t common_dim, + half alpha, const DevicePtr A, std::size_t lda, std::size_t strideA, + const DevicePtr B, std::size_t ldb, std::size_t strideB, + half beta, const DevicePtr C, std::size_t ldc, std::size_t strideC, + std::size_t batchCount) + { + CV_Assert(handle); + + const auto opa = transa ? CUBLAS_OP_T : CUBLAS_OP_N, + opb = transb ? CUBLAS_OP_T : CUBLAS_OP_N; + const auto irows_c = static_cast(rows_c), + icols_c = static_cast(cols_c), + icommon_dim = static_cast(common_dim), + ilda = static_cast(lda), + ildb = static_cast(ldb), + ildc = static_cast(ldc); + + const auto batch_count = static_cast(batchCount); + const auto stride_a = static_cast(strideA), + stride_b = static_cast(strideB), + stride_c = static_cast(strideC); + + CV_Assert(stride_c >= irows_c * icols_c); // output matrices must not overlap + + CUDA4DNN_CHECK_CUBLAS( + cublasHgemmStridedBatched( + handle.get(), + opa, opb, + irows_c, icols_c, icommon_dim, + &alpha, A.get(), ilda, stride_a, + B.get(), ildb, stride_b, + &beta, C.get(), ildc, stride_c, + batch_count + ) + ); + } + + template <> inline + void gemmStridedBatched(const Handle& handle, + bool transa, bool transb, + std::size_t rows_c, std::size_t cols_c, std::size_t common_dim, + float alpha, const DevicePtr A, std::size_t lda, std::size_t strideA, + const DevicePtr B, std::size_t ldb, std::size_t strideB, + float beta, const DevicePtr C, std::size_t ldc, std::size_t strideC, + std::size_t batchCount) + { + CV_Assert(handle); + + const auto opa = transa ? CUBLAS_OP_T : CUBLAS_OP_N, + opb = transb ? CUBLAS_OP_T : CUBLAS_OP_N; + const auto irows_c = static_cast(rows_c), + icols_c = static_cast(cols_c), + icommon_dim = static_cast(common_dim), + ilda = static_cast(lda), + ildb = static_cast(ldb), + ildc = static_cast(ldc); + + const auto batch_count = static_cast(batchCount); + const auto stride_a = static_cast(strideA), + stride_b = static_cast(strideB), + stride_c = static_cast(strideC); + + CV_Assert(stride_c >= irows_c * icols_c); // output matrices must not overlap + + CUDA4DNN_CHECK_CUBLAS( + cublasSgemmStridedBatched( + handle.get(), + opa, opb, + irows_c, icols_c, icommon_dim, + &alpha, A.get(), ilda, stride_a, + B.get(), ildb, stride_b, + &beta, C.get(), ildc, stride_c, + batch_count + ) + ); + } + }}}}} /* namespace cv::dnn::cuda4dnn::csl::cublas */ #endif /* OPENCV_DNN_SRC_CUDA4DNN_CSL_CUBLAS_HPP */ diff --git a/modules/dnn/src/cuda4dnn/csl/tensor.hpp b/modules/dnn/src/cuda4dnn/csl/tensor.hpp index 6e997ab0eb12..5a1286de99d6 100644 --- a/modules/dnn/src/cuda4dnn/csl/tensor.hpp +++ b/modules/dnn/src/cuda4dnn/csl/tensor.hpp @@ -369,6 +369,26 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { shape.erase(std::begin(shape) + axis); } + /** @brief squeezes the tensor + * + * removes leading singleton axes until the tensor's rank is equal to the requested rank + * + * Pre-conditions: + * - the tensor must be non-empty + * - the tensor's rank must be at least two + * - the tensor's rank must be at least the requested rank + * - the tensor must be squeezable up to the requested rank + * + * Exception Guarantee: Strong + */ + void squeeze_to(int r) { + CV_Assert(!empty()); + CV_Assert(rank() >= r); + CV_Assert(std::all_of(std::begin(shape), std::end(shape) - r, [](size_type x){ return x == 1; })); + std::copy(std::end(shape) - r, std::end(shape), std::begin(shape)); + shape.resize(r); + } + /** @brief unsqueezes the tensor * * adds a axis of unit size at the requested before the specified axis @@ -665,6 +685,26 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { shape.erase(std::begin(shape) + axis); } + /** @brief squeezes the tensor + * + * removes leading singleton axes until the tensor's rank is equal to the requested rank + * + * Pre-conditions: + * - the tensor must be non-empty + * - the tensor's rank must be at least two + * - the tensor's rank must be at least the requested rank + * - the tensor must be squeezable up to the requested rank + * + * Exception Guarantee: Strong + */ + void squeeze_to(int r) { + CV_Assert(!empty()); + CV_Assert(rank() >= r); + CV_Assert(std::all_of(std::begin(shape), std::end(shape) - r, [](size_type x){ return x == 1; })); + std::copy(std::end(shape) - r, std::end(shape), std::begin(shape)); + shape.resize(r); + } + /** @brief unsqueezes the tensor * * adds a axis of unit size at the requested before the specified axis @@ -1010,6 +1050,26 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { shape.erase(std::begin(shape) + axis); } + /** @brief squeezes the tensor + * + * removes leading singleton axes until the tensor's rank is equal to the requested rank + * + * Pre-conditions: + * - the tensor must be non-empty + * - the tensor's rank must be at least two + * - the tensor's rank must be at least the requested rank + * - the tensor must be squeezable up to the requested rank + * + * Exception Guarantee: Strong + */ + void squeeze_to(int r) { + CV_Assert(!empty()); + CV_Assert(rank() >= r); + CV_Assert(std::all_of(std::begin(shape), std::end(shape) - r, [](size_type x){ return x == 1; })); + std::copy(std::end(shape) - r, std::end(shape), std::begin(shape)); + shape.resize(r); + } + /** @brief unsqueezes the tensor * * adds a axis of unit size at the requested before the specified axis diff --git a/modules/dnn/src/cuda4dnn/csl/tensor_ops.hpp b/modules/dnn/src/cuda4dnn/csl/tensor_ops.hpp index aeddaf353b01..4ee0e8ab77cf 100644 --- a/modules/dnn/src/cuda4dnn/csl/tensor_ops.hpp +++ b/modules/dnn/src/cuda4dnn/csl/tensor_ops.hpp @@ -44,6 +44,30 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { memcpy(dest.get(), src.get(), dest.size(), stream); } + namespace detail { + template + void assertGEMMCompatiblity(const TensorSpan& result, bool transa, const TensorView& A, bool transb, const TensorView& B) { + /* check dimension requirements for matrix multiplication */ + if (!transa && !transb) { + CV_Assert(A.get_axis_size(-2) == result.get_axis_size(-2)); + CV_Assert(A.get_axis_size(-1) == B.get_axis_size(-2)); + CV_Assert(B.get_axis_size(-1) == result.get_axis_size(-1)); + } else if (!transa && transb) { + CV_Assert(A.get_axis_size(-2) == result.get_axis_size(-2)); + CV_Assert(A.get_axis_size(-1) == B.get_axis_size(-1)); + CV_Assert(B.get_axis_size(-2) == result.get_axis_size(-1)); + } else if (transa && !transb) { + CV_Assert(A.get_axis_size(-1) == result.get_axis_size(-2)); + CV_Assert(A.get_axis_size(-2) == B.get_axis_size(-2)); + CV_Assert(B.get_axis_size(-1) == result.get_axis_size(-1)); + } else { + CV_Assert(A.get_axis_size(-1) == result.get_axis_size(-2)); + CV_Assert(A.get_axis_size(-2) == B.get_axis_size(-1)); + CV_Assert(B.get_axis_size(-2) == result.get_axis_size(-1)); + } + } + } + /** @brief performs generalized matrix-multiplication * * Pre-conditions: @@ -54,29 +78,10 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { */ template inline void gemm(const cublas::Handle& handle, T beta, TensorSpan result, T alpha, bool transa, TensorView A, bool transb, TensorView B) { - /* matrix operations can be performed only on rank two or less tensors */ - CV_Assert(get_effective_rank(A) <= 2 && - get_effective_rank(B) <= 2 && - get_effective_rank(result) <= 2); - - /* check dimension requirements for matrix multiplication */ - if (!transa && !transb) { - CV_Assert(A.get_axis_size(-2) == result.get_axis_size(-2)); - CV_Assert(A.get_axis_size(-1) == B.get_axis_size(-2)); - CV_Assert(B.get_axis_size(-1) == result.get_axis_size(-1)); - } else if (!transa && transb) { - CV_Assert(A.get_axis_size(-2) == result.get_axis_size(-2)); - CV_Assert(A.get_axis_size(-1) == B.get_axis_size(-1)); - CV_Assert(B.get_axis_size(-2) == result.get_axis_size(-1)); - } else if (transa && !transb) { - CV_Assert(A.get_axis_size(-1) == result.get_axis_size(-2)); - CV_Assert(A.get_axis_size(-2) == B.get_axis_size(-2)); - CV_Assert(B.get_axis_size(-1) == result.get_axis_size(-1)); - } else { - CV_Assert(A.get_axis_size(-1) == result.get_axis_size(-2)); - CV_Assert(A.get_axis_size(-2) == B.get_axis_size(-1)); - CV_Assert(B.get_axis_size(-2) == result.get_axis_size(-1)); - } + /* matrix operations can be performed only on tensors with rank two or below */ + CV_Assert(get_effective_rank(A) <= 2); + CV_Assert(get_effective_rank(B) <= 2); + CV_Assert(get_effective_rank(result) <= 2); const auto result_nr = result.get_axis_size(-2); const auto result_nc = result.get_axis_size(-1); @@ -84,6 +89,8 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { const auto A_nc = A.get_axis_size(-1); const auto B_nc = B.get_axis_size(-1); + detail::assertGEMMCompatiblity(result, transa, A, transb, B); + /* tensors are stored in row-major but cublas::gemm operates on column-major matrices * a row-major matrix when read as column-major matrix gives the transpose of the intended matrix * @@ -103,6 +110,47 @@ namespace cv { namespace dnn { namespace cuda4dnn { namespace csl { beta, result.get(), result_nc); } + /** @brief performs generalized matrix-multiplication for a strided batch of matrices + * + * Pre-conditions: + * - A, B and C must be rank three tensors with dimensions (batch, rows, cols) + * - the last two axes of \p A and \p B must meet the mathematical requirements for matrix multiplication + * - \p result must be large enough to hold the result and the matrices must not overlap in memory + * - batch dimension should be same in \p A, \p B and \p result + * + * Exception Guarantee: Basic + */ + template inline + void gemmStridedBatched(const cublas::Handle& handle, T beta, TensorSpan result, T alpha, bool transa, TensorView A, bool transb, TensorView B) { + CV_Assert(A.rank() == 3); + CV_Assert(B.rank() == 3); + CV_Assert(result.rank() == 3); + + const auto batch_size = result.get_axis_size(0); + CV_Assert(batch_size == A.get_axis_size(0)); + CV_Assert(batch_size == B.get_axis_size(0)); + + detail::assertGEMMCompatiblity(result, transa, A, transb, B); + + const auto result_nr = result.get_axis_size(-2); + const auto result_nc = result.get_axis_size(-1); + const auto common_dim = A.get_axis_size(transa ? -2 : -1); + const auto A_nc = A.get_axis_size(-1); + const auto B_nc = B.get_axis_size(-1); + + std::size_t strideA = (A.size() / batch_size), + strideB = (B.size() / batch_size), + strideC = (result.size() / batch_size); + + cublas::gemmStridedBatched(handle, + transb, transa, + result_nc, result_nr, common_dim, + alpha, B.get(), B_nc, strideB, + A.get(), A_nc, strideA, + beta, result.get(), result_nc, strideC, + batch_size); + } + /** @brief performs element-wise addition with broadcasting * * Pre-conditions: diff --git a/modules/dnn/src/cuda4dnn/primitives/matmul.hpp b/modules/dnn/src/cuda4dnn/primitives/matmul.hpp new file mode 100644 index 000000000000..e29036d5f48e --- /dev/null +++ b/modules/dnn/src/cuda4dnn/primitives/matmul.hpp @@ -0,0 +1,95 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_DNN_SRC_CUDA4DNN_PRIMITIVES_MATMUL_HPP +#define OPENCV_DNN_SRC_CUDA4DNN_PRIMITIVES_MATMUL_HPP + +#include "../../op_cuda.hpp" + +#include "../csl/stream.hpp" +#include "../csl/cublas.hpp" +#include "../csl/tensor.hpp" +#include "../csl/tensor_ops.hpp" + +#include + +#include + +namespace cv { namespace dnn { namespace cuda4dnn { + + template + class MatMulOp final : public CUDABackendNode { + public: + using wrapper_type = GetCUDABackendWrapperType; + + MatMulOp(csl::Stream stream_, csl::cublas::Handle handle) + : stream(std::move(stream_)), cublasHandle(std::move(handle)) + { + } + + void forward( + const std::vector>& inputs, + const std::vector>& outputs, + csl::Workspace& workspace) override + { + CV_Assert(inputs.size() == 2 && outputs.size() == 1); + + auto input1_wrapper = inputs[0].dynamicCast(); + auto input1 = input1_wrapper->getView(); + + auto input2_wrapper = inputs[1].dynamicCast(); + auto input2 = input2_wrapper->getView(); + + auto output_wrapper = outputs[0].dynamicCast(); + auto output = output_wrapper->getSpan(); + + auto rank = output.rank(); + CV_Assert(rank == input1.rank()); + CV_Assert(rank == input2.rank()); + CV_Assert(rank >= 2); // 1D MatMul not supported + + for (int i = 0; i < rank - 2; i++) + { + // broadcasting not supported + auto size = output.get_axis_size(i); + CV_Assert(input1.get_axis_size(i) == size); + CV_Assert(input2.get_axis_size(i) == size); + } + + auto m = input1.get_axis_size(-2); + auto n = input1.get_axis_size(-1); + auto k = input2.get_axis_size(-1); + auto b = input1.size() / m / n; + CV_Assert(input2.get_axis_size(-2) == n); + CV_Assert(output.get_axis_size(-2) == m); + CV_Assert(output.get_axis_size(-1) == k); + + if (get_effective_rank(output) <= 2) + { + CV_Assert(b == 1); + CV_Assert(get_effective_rank(input1) <= 2); + CV_Assert(get_effective_rank(input2) <= 2); + csl::tensor_ops::gemm(cublasHandle, 0.0, output, 1.0, false, input1, false, input2); + } + else + { + CV_Assert(rank >= 3); + input1.reshape(b, m, n); + input2.reshape(b, n, k); + output.reshape(b, m, k); + input1.squeeze_to(3); + input2.squeeze_to(3); + output.squeeze_to(3); + csl::tensor_ops::gemmStridedBatched(cublasHandle, 0.0, output, 1.0, false, input1, false, input2); + } + } + + private: + csl::Stream stream; + csl::cublas::Handle cublasHandle; + }; + +}}} /* namespace cv::dnn::cuda4dnn */ + +#endif /* OPENCV_DNN_SRC_CUDA4DNN_PRIMITIVES_MATMUL_HPP */ diff --git a/modules/dnn/src/ie_ngraph.cpp b/modules/dnn/src/ie_ngraph.cpp index 748403271425..6f730a907ae3 100644 --- a/modules/dnn/src/ie_ngraph.cpp +++ b/modules/dnn/src/ie_ngraph.cpp @@ -657,7 +657,11 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net) try { InferenceEngine::IExtensionPtr extension = +#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) + std::make_shared(libName); +#else InferenceEngine::make_so_pointer(libName); +#endif ie.AddExtension(extension, "CPU"); CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << libName); @@ -1005,35 +1009,54 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo reqWrapper->req.SetInput(inpBlobs); reqWrapper->req.SetOutput(outBlobs); +#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) + InferenceEngine::InferRequest infRequest = reqWrapper->req; + NgraphReqWrapper* wrapperPtr = reqWrapper.get(); + CV_Assert(wrapperPtr && "Internal error"); +#else InferenceEngine::IInferRequest::Ptr infRequestPtr = reqWrapper->req; - infRequestPtr->SetUserData(reqWrapper.get(), 0); + CV_Assert(infRequestPtr); + InferenceEngine::IInferRequest& infRequest = *infRequestPtr.get(); + infRequest.SetUserData(reqWrapper.get(), 0); +#endif - infRequestPtr->SetCompletionCallback( - [](InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode status) +#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) + // do NOT capture 'reqWrapper' (smart ptr) in the lambda callback + infRequest.SetCompletionCallback>( + [wrapperPtr](InferenceEngine::InferRequest /*request*/, InferenceEngine::StatusCode status) +#else + infRequest.SetCompletionCallback( + [](InferenceEngine::IInferRequest::Ptr requestPtr, InferenceEngine::StatusCode status) +#endif { CV_LOG_DEBUG(NULL, "DNN(nGraph): completionCallback(" << (int)status << ")"); +#if !INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4) + CV_Assert(requestPtr); + InferenceEngine::IInferRequest& request = *requestPtr.get(); - NgraphReqWrapper* wrapper; - request->GetUserData((void**)&wrapper, 0); - CV_Assert(wrapper && "Internal error"); + NgraphReqWrapper* wrapperPtr; + request.GetUserData((void**)&wrapperPtr, 0); + CV_Assert(wrapperPtr && "Internal error"); +#endif + NgraphReqWrapper& wrapper = *wrapperPtr; size_t processedOutputs = 0; try { - for (; processedOutputs < wrapper->outProms.size(); ++processedOutputs) + for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs) { - const std::string& name = wrapper->outsNames[processedOutputs]; - Mat m = ngraphBlobToMat(wrapper->req.GetBlob(name)); + const std::string& name = wrapper.outsNames[processedOutputs]; + Mat m = ngraphBlobToMat(wrapper.req.GetBlob(name)); try { CV_Assert(status == InferenceEngine::StatusCode::OK); - wrapper->outProms[processedOutputs].setValue(m.clone()); + wrapper.outProms[processedOutputs].setValue(m.clone()); } catch (...) { try { - wrapper->outProms[processedOutputs].setException(std::current_exception()); + wrapper.outProms[processedOutputs].setException(std::current_exception()); } catch(...) { CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation"); } @@ -1043,16 +1066,16 @@ void InfEngineNgraphNet::forward(const std::vector >& outBlo catch (...) { std::exception_ptr e = std::current_exception(); - for (; processedOutputs < wrapper->outProms.size(); ++processedOutputs) + for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs) { try { - wrapper->outProms[processedOutputs].setException(e); + wrapper.outProms[processedOutputs].setException(e); } catch(...) { CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation"); } } } - wrapper->isReady = true; + wrapper.isReady = true; } ); } diff --git a/modules/dnn/src/layers/batch_norm_layer.cpp b/modules/dnn/src/layers/batch_norm_layer.cpp index edd9948db166..e28c964689b9 100644 --- a/modules/dnn/src/layers/batch_norm_layer.cpp +++ b/modules/dnn/src/layers/batch_norm_layer.cpp @@ -35,6 +35,7 @@ namespace dnn class BatchNormLayerImpl CV_FINAL : public BatchNormLayer { public: + Mat origin_weights, origin_bias; Mat weights_, bias_; UMat umat_weight, umat_bias; mutable int dims; @@ -88,11 +89,11 @@ class BatchNormLayerImpl CV_FINAL : public BatchNormLayer const float* weightsData = hasWeights ? blobs[weightsBlobIndex].ptr() : 0; const float* biasData = hasBias ? blobs[biasBlobIndex].ptr() : 0; - weights_.create(1, (int)n, CV_32F); - bias_.create(1, (int)n, CV_32F); + origin_weights.create(1, (int)n, CV_32F); + origin_bias.create(1, (int)n, CV_32F); - float* dstWeightsData = weights_.ptr(); - float* dstBiasData = bias_.ptr(); + float* dstWeightsData = origin_weights.ptr(); + float* dstBiasData = origin_bias.ptr(); for (size_t i = 0; i < n; ++i) { @@ -100,15 +101,12 @@ class BatchNormLayerImpl CV_FINAL : public BatchNormLayer dstWeightsData[i] = w; dstBiasData[i] = (hasBias ? biasData[i] : 0.0f) - w * meanData[i] * varMeanScale; } - // We will use blobs to store origin weights and bias to restore them in case of reinitialization. - weights_.copyTo(blobs[0].reshape(1, 1)); - bias_.copyTo(blobs[1].reshape(1, 1)); } virtual void finalize(InputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE { - blobs[0].reshape(1, 1).copyTo(weights_); - blobs[1].reshape(1, 1).copyTo(bias_); + origin_weights.reshape(1, 1).copyTo(weights_); + origin_bias.reshape(1, 1).copyTo(bias_); } void getScaleShift(Mat& scale, Mat& shift) const CV_OVERRIDE diff --git a/modules/dnn/src/layers/fully_connected_layer.cpp b/modules/dnn/src/layers/fully_connected_layer.cpp index 709420c3caf5..d9c1fa65c143 100644 --- a/modules/dnn/src/layers/fully_connected_layer.cpp +++ b/modules/dnn/src/layers/fully_connected_layer.cpp @@ -55,6 +55,7 @@ using namespace cv::dnn::ocl4dnn; #endif #ifdef HAVE_CUDA +#include "../cuda4dnn/primitives/matmul.hpp" #include "../cuda4dnn/primitives/inner_product.hpp" using namespace cv::dnn::cuda4dnn; #endif @@ -523,10 +524,14 @@ class FullyConnectedLayerImpl CV_FINAL : public InnerProductLayer { auto context = reinterpret_cast(context_); - auto input_wrapper = inputs[0].dynamicCast(); + if (weightsMat.empty()) + { + CV_Assert(!bias); + return make_cuda_node(preferableTarget, std::move(context->stream), std::move(context->cublas_handle)); + } + auto input_wrapper = inputs[0].dynamicCast(); auto flatten_start_axis = normalize_axis(axis, input_wrapper->getRank()); - auto biasMat_ = bias ? biasMat : Mat(); return make_cuda_node(preferableTarget, std::move(context->stream), std::move(context->cublas_handle), flatten_start_axis, weightsMat, biasMat_); } diff --git a/modules/dnn/src/layers/normalize_bbox_layer.cpp b/modules/dnn/src/layers/normalize_bbox_layer.cpp index 24559543e19b..236f2e43f11e 100644 --- a/modules/dnn/src/layers/normalize_bbox_layer.cpp +++ b/modules/dnn/src/layers/normalize_bbox_layer.cpp @@ -338,7 +338,7 @@ class NormalizeBBoxLayerImpl CV_FINAL : public NormalizeBBoxLayer std::iota(axes_data.begin(), axes_data.end(), 1); } auto axes = std::make_shared(ngraph::element::i64, ngraph::Shape{axes_data.size()}, axes_data); - auto norm = std::make_shared(ieInpNode, axes, epsilon, ngraph::op::EpsMode::ADD); + auto norm = std::make_shared(ieInpNode, axes, epsilon, ngraph::op::EpsMode::ADD); CV_Assert(blobs.empty() || numChannels == blobs[0].total()); std::vector shape(ieInpNode->get_shape().size(), 1); diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 98714bbd5c29..1f240cae466e 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -1954,6 +1954,23 @@ void ONNXImporter::handleNode(const opencv_onnx::NodeProto& node_proto_) addConstant(layerParams.name, concatenated[0]); return; } + else + { + for (int i = 0; i < node_proto.input_size(); ++i) + { + if (constBlobs.find(node_proto.input(i)) != constBlobs.end()) + { + LayerParams constParams; + constParams.name = node_proto.input(i); + constParams.type = "Const"; + constParams.blobs.push_back(getBlob(node_proto, i)); + + opencv_onnx::NodeProto proto; + proto.add_output(constParams.name); + addLayer(constParams, proto); + } + } + } } else if (layer_type == "Resize") { diff --git a/modules/dnn/src/op_inf_engine.hpp b/modules/dnn/src/op_inf_engine.hpp index f52334bc4597..ab2f161eaf1b 100644 --- a/modules/dnn/src/op_inf_engine.hpp +++ b/modules/dnn/src/op_inf_engine.hpp @@ -30,10 +30,11 @@ #define INF_ENGINE_RELEASE_2021_1 2021010000 #define INF_ENGINE_RELEASE_2021_2 2021020000 #define INF_ENGINE_RELEASE_2021_3 2021030000 +#define INF_ENGINE_RELEASE_2021_4 2021040000 #ifndef INF_ENGINE_RELEASE -#warning("IE version have not been provided via command-line. Using 2021.3 by default") -#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_3 +#warning("IE version have not been provided via command-line. Using 2021.4 by default") +#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_4 #endif #define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000)) diff --git a/modules/dnn/src/tensorflow/tf_importer.cpp b/modules/dnn/src/tensorflow/tf_importer.cpp index 65695b85045d..15f88007b4d1 100644 --- a/modules/dnn/src/tensorflow/tf_importer.cpp +++ b/modules/dnn/src/tensorflow/tf_importer.cpp @@ -32,6 +32,8 @@ namespace cv { namespace dnn { CV__DNN_INLINE_NS_BEGIN +extern bool DNN_DIAGNOSTICS_RUN; + #if HAVE_PROTOBUF using ::google::protobuf::RepeatedField; @@ -471,6 +473,7 @@ class TFImporter TFImporter(Net& net, const char *dataModel, size_t lenModel, const char *dataConfig = NULL, size_t lenConfig = 0); protected: + std::unique_ptr utilNet; Net& dstNet; void populateNet(); @@ -510,2058 +513,2311 @@ class TFImporter private: void addPermuteLayer(const int* order, const std::string& permName, Pin& inpId); + + typedef void (TFImporter::*TFImporterNodeParser)(tensorflow::GraphDef&, const tensorflow::NodeDef&, LayerParams&); + typedef std::map DispatchMap; + + const DispatchMap dispatch; + static const DispatchMap buildDispatchMap(); + + void parseConvolution (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseBias (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseMatMul (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseReshape (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseFlatten (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseTranspose (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseConstant (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseLrn (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseConcat (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseMaxPool (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseAvgPool (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseMaxPoolGrad (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parsePlaceholder (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseSplit (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseSlice (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseStridedSlice (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseMul (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseFusedBatchNorm (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseConv2DBackpropInput(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseBlockLSTM (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseResize (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseL2Normalize (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parsePriorBox (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseSoftmax (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseCropAndResize (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseMean (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parsePack (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseClipByValue (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseLeakyRelu (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + void parseActivation (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); + + void parseCustomLayer (tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams); }; -TFImporter::TFImporter(Net& net, const char *model, const char *config) - : dstNet(net) +const TFImporter::DispatchMap TFImporter::buildDispatchMap() { - if (model && model[0]) - { - CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow model from file: " << model); - ReadTFNetParamsFromBinaryFileOrDie(model, &netBin); - } - if (config && config[0]) - { - CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow config from file: " << config); - ReadTFNetParamsFromTextFileOrDie(config, &netTxt); - } - - populateNet(); + static DispatchMap dispatch; + dispatch["Conv2D"] = dispatch["SpaceToBatchND"] = dispatch["DepthwiseConv2dNative"] = + dispatch["Pad"] = dispatch["MirrorPad"] = dispatch["Conv3D"] = &TFImporter::parseConvolution; + dispatch["BiasAdd"] = dispatch["Add"] = dispatch["AddV2"] = dispatch["Sub"] = dispatch["AddN"] = &TFImporter::parseBias; + dispatch["MatMul"] = &TFImporter::parseMatMul; + dispatch["Reshape"] = &TFImporter::parseReshape; + dispatch["Flatten"] = dispatch["Squeeze"] = &TFImporter::parseFlatten; + dispatch["Transpose"] = &TFImporter::parseTranspose; + dispatch["Const"] = &TFImporter::parseConstant; + dispatch["LRN"] = &TFImporter::parseLrn; + dispatch["Concat"] = dispatch["ConcatV2"] = &TFImporter::parseConcat; + dispatch["MaxPool"] = dispatch["MaxPool3D"] = &TFImporter::parseMaxPool; + dispatch["AvgPool"] = dispatch["AvgPool3D"] = &TFImporter::parseAvgPool; + dispatch["MaxPoolGrad"] = &TFImporter::parseMaxPoolGrad; + dispatch["Placeholder"] = &TFImporter::parsePlaceholder; + dispatch["Split"] = &TFImporter::parseSplit; + dispatch["Slice"] = &TFImporter::parseSlice; + dispatch["StridedSlice"] = &TFImporter::parseStridedSlice; + dispatch["Mul"] = dispatch["RealDiv"] = &TFImporter::parseMul; + dispatch["FusedBatchNorm"] = dispatch["FusedBatchNormV3"] = &TFImporter::parseFusedBatchNorm; + dispatch["Conv2DBackpropInput"] = &TFImporter::parseConv2DBackpropInput; + dispatch["BlockLSTM"] = &TFImporter::parseBlockLSTM; + dispatch["ResizeNearestNeighbor"] = dispatch["ResizeBilinear"] = dispatch["FusedResizeAndPadConv2D"] = &TFImporter::parseResize; + dispatch["L2Normalize"] = &TFImporter::parseL2Normalize; + dispatch["PriorBox"] = &TFImporter::parsePriorBox; + dispatch["Softmax"] = &TFImporter::parseSoftmax; + dispatch["CropAndResize"] = &TFImporter::parseCropAndResize; + dispatch["Mean"] = dispatch["Sum"] = &TFImporter::parseMean; + dispatch["Pack"] = &TFImporter::parsePack; + dispatch["ClipByValue"] = &TFImporter::parseClipByValue; + dispatch["LeakyRelu"] = &TFImporter::parseLeakyRelu; + dispatch["Abs"] = dispatch["Tanh"] = dispatch["Sigmoid"] = dispatch["Relu"] = + dispatch["Elu"] = dispatch["Exp"] = dispatch["Identity"] = dispatch["Relu6"] = &TFImporter::parseActivation; + + return dispatch; } -TFImporter::TFImporter( - Net& net, - const char *dataModel, size_t lenModel, - const char *dataConfig, size_t lenConfig -) - : dstNet(net) +void TFImporter::parseConvolution(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer_, LayerParams& layerParams) { - if (dataModel != NULL && lenModel > 0) - { - CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow model from memory (" << lenModel << " bytes)"); - ReadTFNetParamsFromBinaryBufferOrDie(dataModel, lenModel, &netBin); - } - if (dataConfig != NULL && lenConfig > 0) + tensorflow::NodeDef layer = layer_; + std::string name = layer.name(); + std::string type = layer.op(); + int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + // The first node of dilated convolution subgraph. + // Extract input node, dilation rate and paddings. + std::string input = layer.input(0); + StrIntVector next_layers; + if (type == "SpaceToBatchND" || type == "Pad") { - CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow config from memory (" << lenConfig << " bytes)"); - ReadTFNetParamsFromTextBufferOrDie(dataConfig, lenConfig, &netTxt); + next_layers = getNextLayers(net, name, "Conv2D"); + if (next_layers.empty()) + next_layers = getNextLayers(net, name, "DepthwiseConv2dNative"); } - populateNet(); -} - -void TFImporter::kernelFromTensor(const tensorflow::TensorProto &tensor, Mat &dstBlob) -{ - MatShape shape; - blobShapeFromTensor(tensor, shape); - int dims = (int)shape.size(); - - // TODO: other blob types - CV_Assert(tensor.dtype() == tensorflow::DT_FLOAT || - tensor.dtype() == tensorflow::DT_HALF); - CV_Assert(dims == 4 || dims == 5); - int out_c, input_c, depth, height, width; - if (dims == 4) + if (type == "SpaceToBatchND") { - // REORDER kernel HWIO to OIHW - swap(shape[0], shape[2]); // IWHO - swap(shape[1], shape[3]); // IOHW - swap(shape[0], shape[1]); // OIHW - depth = 1; height = shape[2]; width = shape[3]; + // op: "SpaceToBatchND" + // input: "input" + // input: "SpaceToBatchND/block_shape" + // input: "SpaceToBatchND/paddings" + CV_CheckEQ(num_inputs, 3, ""); + + DictValue dilation = parseDims(getConstBlob(layer, value_id, 1)); + CV_Assert(dilation.size() == 2); + layerParams.set("dilation_h", dilation.get(0)); + layerParams.set("dilation_w", dilation.get(1)); + + Mat paddings; + parseTensor(getConstBlob(layer, value_id, 2), paddings); + + // paddings is a 2x2 matrix: [[top, bot], [left, right]] + layerParams.set("pad_h", paddings.at(0)); + layerParams.set("pad_w", paddings.at(2)); + + CV_Assert(next_layers.size() == 1); + layers_to_ignore.insert(next_layers[0].first); + + // FIXIT don't override, rewrite this code + layer = net.node(next_layers[0].second); + name = layer.name(); + type = layer.op(); + num_inputs = layer.input_size(); + CV_LOG_DEBUG(NULL, "DNN/TF: switched to layer " << name << " @ " << type << ") with " << num_inputs << " inputs"); } - else + else if (type == "Pad" || type == "MirrorPad") { - // REORDER kernel DHWIO to OIDHW - swap(shape[0], shape[4]); // OHWID - swap(shape[1], shape[3]); // OIWHD - swap(shape[2], shape[4]); // OIDHW - depth = shape[2]; height = shape[3]; width = shape[4]; - } - out_c = shape[0]; input_c = shape[1]; + Mat paddings = getTensorContent(getConstBlob(layer, value_id, 1)); + CV_Assert(paddings.type() == CV_32SC1); + if (paddings.total() == 8) + { + // Perhaps, we have NHWC padding dimensions order. + // N H W C + // 0 1 2 3 4 5 6 7 + std::swap(paddings.at(2), paddings.at(6)); + std::swap(paddings.at(3), paddings.at(7)); + // N C W H + // 0 1 2 3 4 5 6 7 + std::swap(paddings.at(4), paddings.at(6)); + std::swap(paddings.at(5), paddings.at(7)); + // N C H W + // 0 1 2 3 4 5 6 7 + } - dstBlob.create(shape, CV_32F); + if (next_layers.empty() || paddings.total() != 8 || + paddings.at(4) != paddings.at(5) || + paddings.at(6) != paddings.at(7) || type == "MirrorPad") + { + // Just a single padding layer. + layerParams.set("paddings", DictValue::arrayInt((int*)paddings.data, paddings.total())); + if (type == "MirrorPad") + layerParams.set("type", "reflect"); - Mat tensorContent = getTensorContent(tensor, /*no copy*/false); - int size = tensorContent.total(); - CV_Assert(size == (int)dstBlob.total()); + int id = dstNet.addLayer(name, "Padding", layerParams); + layer_id[name] = id; - float *dstData = dstBlob.ptr(); - const float *data = reinterpret_cast(tensorContent.data); + connect(layer_id, dstNet, parsePin(input), id, 0); + return; + } + else + { + // Merge with subsequent convolutional layer. + CV_Assert(next_layers.size() == 1); - int total = out_c * input_c * depth * height * width; - for (int i_oc = 0; i_oc < out_c; i_oc++) { - for (int i_ic = 0; i_ic < input_c; i_ic++) { - for (int i_d = 0; i_d < depth; i_d++) { - for (int i_h = 0; i_h < height; i_h++) { - for (int i_w = 0; i_w < width; i_w++) { - int dst_i = input_c * depth * height * width * i_oc + - depth * height * width * i_ic + height * width * i_d + width * i_h + i_w; - int src_i = out_c * input_c * width * height * i_d + - out_c * input_c * width * i_h + out_c * input_c * i_w + out_c * i_ic + i_oc; - CV_Assert(dst_i < total); - CV_Assert(src_i < total); - dstData[dst_i] = data[src_i]; - } - } - } + layerParams.set("pad_h", paddings.at(4)); + layerParams.set("pad_w", paddings.at(6)); + + layers_to_ignore.insert(next_layers[0].first); + + // FIXIT don't override, rewrite this code + layer = net.node(next_layers[0].second); + name = layer.name(); + type = layer.op(); + num_inputs = layer.input_size(); + CV_LOG_DEBUG(NULL, "DNN/TF: switched to layer " << name << " @ " << type << ") with " << num_inputs << " inputs"); } } -} -void TFImporter::connect(const std::map& layers_name_id_map, Net& network, const Pin& outPin, - const int input_layer_id, const int input_blob_id) -{ - std::map::const_iterator it = layers_name_id_map.find(outPin.name); - if (it == layers_name_id_map.end()) - CV_Error(Error::StsError, "Input layer not found: " + outPin.name); + // For the object detection networks, TensorFlow Object Detection API + // predicts deltas for bounding boxes in yxYX (ymin, xmin, ymax, xmax) + // order. We can manage it at DetectionOutput layer parsing predictions + // or shuffle last convolution's weights. + bool locPredTransposed = hasLayerAttr(layer, "loc_pred_transposed") && + getLayerAttr(layer, "loc_pred_transposed").b(); - std::vector::iterator inpNameIt = std::find(netInputsNames.begin(), netInputsNames.end(), outPin.name); - int blobIndex; - if (inpNameIt == netInputsNames.end()) - blobIndex = outPin.blobIndex; - else - blobIndex = inpNameIt - netInputsNames.begin(); - network.connect(it->second, blobIndex, input_layer_id, input_blob_id); -} + layerParams.set("bias_term", false); + layerParams.blobs.resize(1); -void TFImporter::connectToAllBlobs(const std::map& layer_id, Net& network, const Pin& outPin, - const int input_layer_id, const int input_blobs_count) -{ - for (int input_blob_id = 0; input_blob_id < input_blobs_count; input_blob_id++) - connect(layer_id, network, outPin, input_layer_id, input_blob_id); -} + next_layers = getNextLayers(net, name, "BiasAdd"); + if (next_layers.size() == 1) { + layerParams.set("bias_term", true); + layerParams.blobs.resize(2); -const tensorflow::TensorProto& TFImporter::getConstBlob(const tensorflow::NodeDef &layer, std::map const_layers, - int input_blob_index, int* actual_inp_blob_idx) { - if (input_blob_index == -1) { - for(int i = 0; i < layer.input_size(); i++) { - Pin input = parsePin(layer.input(i)); - if (const_layers.find(input.name) != const_layers.end()) { - if (input_blob_index != -1) - CV_Error(Error::StsError, "More than one input is Const op"); + int weights_layer_index = next_layers[0].second; - input_blob_index = i; + blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]); + ExcludeLayer(net, weights_layer_index, 0, false); + layers_to_ignore.insert(next_layers[0].first); + + // Shuffle bias from yxYX to xyXY. + if (locPredTransposed) + { + const int numWeights = layerParams.blobs[1].total(); + float* biasData = reinterpret_cast(layerParams.blobs[1].data); + CV_Assert(numWeights % 4 == 0); + for (int i = 0; i < numWeights; i += 2) + { + std::swap(biasData[i], biasData[i + 1]); } } } - if (input_blob_index == -1) - CV_Error(Error::StsError, "Const input blob for weights not found"); - - Pin kernel_inp = parsePin(layer.input(input_blob_index)); - if (const_layers.find(kernel_inp.name) == const_layers.end()) - CV_Error(Error::StsError, "Input [" + layer.input(input_blob_index) + - "] for node [" + layer.name() + "] not found"); - if (kernel_inp.blobIndex != 0) - CV_Error(Error::StsError, "Unsupported kernel input"); + int kernelTensorInpId = -1; + const tensorflow::TensorProto& kernelTensor = getConstBlob(layer, value_id, -1, &kernelTensorInpId); + const String kernelTensorName = layer.input(kernelTensorInpId); + std::map::iterator sharedWeightsIt = sharedWeights.find(kernelTensorName); + if (sharedWeightsIt == sharedWeights.end()) + { + kernelFromTensor(kernelTensor, layerParams.blobs[0]); + releaseTensor(const_cast(&kernelTensor)); + + int* kshape = layerParams.blobs[0].size.p; + const int outCh = kshape[0]; + const int inCh = kshape[1]; + const int height = kshape[2]; + const int width = kshape[3]; + if (type == "DepthwiseConv2dNative") + { + CV_Assert(!locPredTransposed); + const int chMultiplier = kshape[0]; + + Mat copy = layerParams.blobs[0].clone(); + float* src = (float*)copy.data; + float* dst = (float*)layerParams.blobs[0].data; + for (int i = 0; i < chMultiplier; ++i) + for (int j = 0; j < inCh; ++j) + for (int s = 0; s < height * width; ++s) + { + int src_i = (i * inCh + j) * height * width + s; + int dst_i = (j * chMultiplier + i) * height* width + s; + dst[dst_i] = src[src_i]; + } + // TODO Use reshape instead + kshape[0] = inCh * chMultiplier; + kshape[1] = 1; + size_t* kstep = layerParams.blobs[0].step.p; + kstep[0] = kstep[1]; // fix steps too + } - if(actual_inp_blob_idx) { - *actual_inp_blob_idx = input_blob_index; + // Shuffle output channels from yxYX to xyXY. + if (locPredTransposed) + { + const int slice = height * width * inCh; + for (int i = 0; i < outCh; i += 2) + { + cv::Mat src(1, slice, CV_32F, layerParams.blobs[0].ptr(i)); + cv::Mat dst(1, slice, CV_32F, layerParams.blobs[0].ptr(i + 1)); + std::swap_ranges(src.begin(), src.end(), dst.begin()); + } + } + sharedWeights[kernelTensorName] = layerParams.blobs[0]; } - - int nodeIdx = const_layers.at(kernel_inp.name); - if (nodeIdx < netBin.node_size() && netBin.node(nodeIdx).name() == kernel_inp.name) + else { - return netBin.node(nodeIdx).attr().at("value").tensor(); + layerParams.blobs[0] = sharedWeightsIt->second; } - else + Mat weights = layerParams.blobs[0]; + layerParams.set("kernel_size", DictValue::arrayInt(&weights.size[2], weights.dims - 2)); + + layerParams.set("num_output", layerParams.blobs[0].size[0]); + + setStrides(layerParams, layer); + if (!layerParams.has("pad_w") && !layerParams.has("pad_h")) + setPadding(layerParams, layer); + + // The final node of dilated convolution subgraph. + next_layers = getNextLayers(net, name, "BatchToSpaceND"); + if (!next_layers.empty()) { - CV_Assert_N(nodeIdx < netTxt.node_size(), - netTxt.node(nodeIdx).name() == kernel_inp.name); - return netTxt.node(nodeIdx).attr().at("value").tensor(); + CV_Assert(next_layers.size() == 1); + ExcludeLayer(net, next_layers[0].second, 0, false); + layers_to_ignore.insert(next_layers[0].first); } + + int id = dstNet.addLayer(name, "Convolution", layerParams); + layer_id[name] = id; + + // one input only + connect(layer_id, dstNet, parsePin(input), id, 0); + + + if (getDataLayout(name, data_layouts) == DATA_LAYOUT_UNKNOWN) + data_layouts[name] = DATA_LAYOUT_NHWC; } -static void addConstNodes(tensorflow::GraphDef& net, std::map& const_layers, - std::set& layers_to_ignore) +void TFImporter::parseBias(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) { - CV_LOG_DEBUG(NULL, "DNN/TF: addConstNodes(): handling " << net.node_size() << " nodes..."); - for (int li = 0; li < net.node_size(); li++) + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + bool haveConst = false; + for(int ii = 0; !haveConst && ii < num_inputs; ++ii) { - const tensorflow::NodeDef &layer = net.node(li); - String name = layer.name(); - String type = layer.op(); + Pin input = parsePin(layer.input(ii)); + haveConst = value_id.find(input.name) != value_id.end(); + } + CV_Assert(!haveConst || num_inputs == 2); - //CV_LOG_DEBUG(NULL, "DNN/TF: layer_id=" << li << " - '" << name << "' @ " << type); + if (haveConst) + { + Mat values = getTensorContent(getConstBlob(layer, value_id)); + CV_Assert(values.type() == CV_32FC1); + if (type == "Sub") + values *= -1.0f; - try + int id; + if (values.total() == 1) // is a scalar. { - if (type == "Dequantize") - { - // Example of Dequantize node: - // name: "conv2d_1/bias" - // op: "Dequantize" - // input: "conv2d_1/bias_quantized_const" (tensor of dtype DT_QUINT8) - // input: "conv2d_1/bias_quantized_min" - // input: "conv2d_1/bias_quantized_max" - // attr { key: "T" value { type: DT_QUINT8 } } (quantized type) - // attr { key: "mode" value { s: "MIN_FIRST" } } (quantization technique) - CV_CheckEQ(layer.input_size(), 3, "Dequantize: 3 inputs is supported only"); - for (int i = 0; i < 3; ++i) - CV_Assert(const_layers.find(layer.input(i)) != const_layers.end()); - CV_Assert(hasLayerAttr(layer, "mode") && - getLayerAttr(layer, "mode").s() == "MIN_FIRST"); + layerParams.set("shift", values.at(0)); + id = dstNet.addLayer(name, "Power", layerParams); + } + else // is a vector + { + layerParams.blobs.resize(1, values); + id = dstNet.addLayer(name, "Shift", layerParams); + } + layer_id[name] = id; - int tensorId = const_layers[layer.input(0)]; - int minId = const_layers[layer.input(1)]; - int maxId = const_layers[layer.input(2)]; + // one input only + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + } + else + { + layerParams.set("operation", "sum"); + if (type == "Sub") + { + static float subCoeffs[] = {1.f, -1.f}; + layerParams.set("coeff", DictValue::arrayReal(subCoeffs, 2)); + } - tensorflow::TensorProto* tensor = net.mutable_node(tensorId) - ->mutable_attr()->at("value") - .mutable_tensor(); - CV_CheckEQ((int)tensor->dtype(), (int)tensorflow::DT_QUINT8, ""); + int id = dstNet.addLayer(name, "Eltwise", layerParams); + layer_id[name] = id; - Mat qMin = getTensorContent(net.node(minId).attr().at("value").tensor()); - Mat qMax = getTensorContent(net.node(maxId).attr().at("value").tensor()); - CV_CheckEQ(qMin.total(), (size_t)1, ""); - CV_CheckTypeEQ(qMin.type(), CV_32FC1, ""); - CV_CheckEQ(qMax.total(), (size_t)1, ""); - CV_CheckTypeEQ(qMax.type(), CV_32FC1, ""); + for (int ii = 0; ii < num_inputs; ii++) + { + Pin inp = parsePin(layer.input(ii)); + if (layer_id.find(inp.name) == layer_id.end()) + CV_Error(Error::StsError, "Input layer not found: " + inp.name); + connect(layer_id, dstNet, inp, id, ii); + } + } +} - Mat content = getTensorContent(*tensor); +void TFImporter::parseMatMul(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - float minVal = qMin.at(0); - float rangeScale = (qMax.at(0) - minVal) / 255; - CV_Assert(rangeScale >= 0); - content.convertTo(content, CV_32FC1, rangeScale, - rangeScale * cvRound(minVal / rangeScale)); + CV_CheckEQ(num_inputs, 2, ""); - tensor->set_dtype(tensorflow::DT_FLOAT); - tensor->set_tensor_content(content.data, content.total() * content.elemSize1()); + // For the object detection networks, TensorFlow Object Detection API + // predicts deltas for bounding boxes in yxYX (ymin, xmin, ymax, xmax) + // order. We can manage it at DetectionOutput layer parsing predictions + // or shuffle last Faster-RCNN's matmul weights. + bool locPredTransposed = hasLayerAttr(layer, "loc_pred_transposed") && + getLayerAttr(layer, "loc_pred_transposed").b(); - net.mutable_node(tensorId)->set_name(name); - CV_Assert(const_layers.insert(std::make_pair(name, tensorId)).second); - layers_to_ignore.insert(name); - continue; - } - else if (type != "Const") - continue; // only Const parameters are supported + layerParams.set("bias_term", false); + layerParams.blobs.resize(1); - if (layer.attr().find("value") != layer.attr().end()) + StrIntVector next_layers = getNextLayers(net, name, "BiasAdd"); // FIXIT Use layers fusion instead + if (next_layers.empty()) + { + next_layers = getNextLayers(net, name, "Add"); + } + if (next_layers.size() == 1) { + layerParams.set("bias_term", true); + layerParams.blobs.resize(2); + + int weights_layer_index = next_layers[0].second; + blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]); + ExcludeLayer(net, weights_layer_index, 0, false); + layers_to_ignore.insert(next_layers[0].first); + + if (locPredTransposed) + { + const int numWeights = layerParams.blobs[1].total(); + float* biasData = reinterpret_cast(layerParams.blobs[1].data); + CV_Assert(numWeights % 4 == 0); + for (int i = 0; i < numWeights; i += 2) { - CV_Assert(const_layers.insert(std::make_pair(name, li)).second); + std::swap(biasData[i], biasData[i + 1]); } - layers_to_ignore.insert(name); } - catch (const std::exception& e) + } + + int kernel_blob_index = -1; + const tensorflow::TensorProto& kernelTensor = getConstBlob(layer, value_id, -1, &kernel_blob_index); + const String kernelTensorName = layer.input(kernel_blob_index); + std::map::iterator sharedWeightsIt = sharedWeights.find(kernelTensorName); + if (sharedWeightsIt == sharedWeights.end()) + { + blobFromTensor(kernelTensor, layerParams.blobs[0]); + releaseTensor(const_cast(&kernelTensor)); + sharedWeights[kernelTensorName] = layerParams.blobs[0]; + } + else + { + layerParams.blobs[0] = sharedWeightsIt->second; + } + + if (kernel_blob_index == 1) { // In this case output is computed by x*W formula - W should be transposed + Mat data = layerParams.blobs[0].t(); + layerParams.blobs[0] = data.clone(); + } + + layerParams.set("num_output", layerParams.blobs[0].size[0]); + if (locPredTransposed) + { + CV_Assert(layerParams.blobs[0].dims == 2); + for (int i = 0; i < layerParams.blobs[0].size[0]; i += 2) { - CV_LOG_ERROR(NULL, "DNN/TF: Can't handle node='" << name << "'. Exception: " << e.what()); - throw; + cv::Mat src = layerParams.blobs[0].row(i); + cv::Mat dst = layerParams.blobs[0].row(i + 1); + std::swap_ranges(src.begin(), src.end(), dst.begin()); } } - CV_LOG_DEBUG(NULL, "DNN/TF: layers_to_ignore.size() = " << layers_to_ignore.size()); + + int id = dstNet.addLayer(name, "InnerProduct", layerParams); + layer_id[name] = id; + + // one input only + int input_blob_index = kernel_blob_index == 0 ? 1 : 0; + connect(layer_id, dstNet, parsePin(layer.input(input_blob_index)), id, 0); + data_layouts[name] = DATA_LAYOUT_PLANAR; } -// If all inputs of specific layer have the same data layout we can say that -// this layer's output has this data layout too. Returns DATA_LAYOUT_UNKNOWN otherwise. -DataLayout TFImporter::predictOutputDataLayout(const tensorflow::NodeDef& layer) +void TFImporter::parseReshape(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) { - DataLayout layout = getDataLayout(layer); - if (layout != DATA_LAYOUT_UNKNOWN) - { - CV_LOG_DEBUG(NULL, "DNN/TF: predictOutputDataLayout(" << layer.name() << " @ " << layer.op() << ") => " << (int)layout << " (from attrs)"); - return layout; - } - - // Determine layout by layer's inputs - for (int i = 0, n = layer.input_size(); i < n; ++i) + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + Pin inpId = parsePin(layer.input(0)); + DataLayout inpLayout = getDataLayout(layer.input(0), data_layouts); + // There are two possible implementations: reshape an input using + // predefined sizes or use a second input blob as a source of new shape. + if (value_id.find(layer.input(1)) != value_id.end()) { - std::map::const_iterator it = data_layouts.find(getNodeName(layer.input(i))); - if (it != data_layouts.end()) + Mat newShape = getTensorContent(getConstBlob(layer, value_id, 1)); + int newShapeSize = newShape.total(); + bool hasSwap = false; + if (newShapeSize == 4 && hasAllOnes(newShape, 0, 2)) { - if (layout != DATA_LAYOUT_UNKNOWN) + // NHWC->NCHW + std::swap(*newShape.ptr(0, 2), *newShape.ptr(0, 3)); + std::swap(*newShape.ptr(0, 1), *newShape.ptr(0, 2)); + hasSwap = true; + } + if (inpLayout == DATA_LAYOUT_NHWC) + { + if (newShapeSize >= 2 || newShape.at(1) == 1) { - if (it->second != layout && it->second != DATA_LAYOUT_UNKNOWN) - return DATA_LAYOUT_UNKNOWN; + int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. + addPermuteLayer(order, name + "/nhwc", inpId); + if (newShapeSize < 4) + { + inpLayout = DATA_LAYOUT_NCHW; + } + else + { + inpLayout = DATA_LAYOUT_NHWC; + } } - else - layout = it->second; } - } + layerParams.set("dim", DictValue::arrayInt(newShape.ptr(), newShapeSize)); - if (layout != DATA_LAYOUT_UNKNOWN) + int id = dstNet.addLayer(name, "Reshape", layerParams); + layer_id[name] = id; + + // one input only + connect(layer_id, dstNet, inpId, id, 0); + inpId = Pin(name); + + if ((inpLayout == DATA_LAYOUT_NHWC || inpLayout == DATA_LAYOUT_UNKNOWN || inpLayout == DATA_LAYOUT_PLANAR) && + newShapeSize == 4 && !hasSwap) + { + int order[] = {0, 3, 1, 2}; // Transform back to OpenCV's NCHW. + addPermuteLayer(order, name + "/nchw", inpId); + inpLayout = DATA_LAYOUT_NCHW; + } + + data_layouts[name] = newShapeSize == 2 ? DATA_LAYOUT_PLANAR : inpLayout; + } + else { - CV_LOG_DEBUG(NULL, "DNN/TF: predictOutputDataLayout(" << layer.name() << " @ " << layer.op() << ") => " << (int)layout << " (from inputs)"); - return layout; + int id = dstNet.addLayer(name, "Reshape", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, inpId, id, 0); + connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1); + data_layouts[name] = inpLayout; } - - // Determine layout by layer's consumers recursively. - std::map::const_iterator it = data_layouts.find(layer.name()); - CV_Assert(it != data_layouts.end()); - return it->second; } -void TFImporter::populateNet() +void TFImporter::parseFlatten(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) { - CV_Assert(netBin.ByteSize() || netTxt.ByteSize()); - - CV_LOG_INFO(NULL, "DNN/TF: parsing model" - << (netBin.has_versions() ? cv::format(" produced by TF v%d (min_consumer=%d)", (int)netBin.versions().producer(), (int)netBin.versions().min_consumer()) : cv::String(" (N/A version info)")) - << ". Number of nodes = " << netBin.node_size() - ); - - if (netTxt.ByteSize()) + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + Pin inpId = parsePin(layer.input(0)); + int inpLayout = getDataLayout(layer.input(0), data_layouts); + if (type == "Squeeze") { - CV_LOG_INFO(NULL, "DNN/TF: parsing config" - << (netTxt.has_versions() ? cv::format(" produced by TF v%d (min_consumer=%d)", (int)netTxt.versions().producer(), (int)netTxt.versions().min_consumer()) : cv::String(" (N/A version info)")) - << ". Number of nodes = " << netTxt.node_size() - ); - - RemoveIdentityOps(netBin); - CV_LOG_DEBUG(NULL, "DNN/TF: RemoveIdentityOps(model) => " << netBin.node_size() << " nodes"); - RemoveIdentityOps(netTxt); - CV_LOG_DEBUG(NULL, "DNN/TF: RemoveIdentityOps(config) => " << netTxt.node_size() << " nodes"); - - sortByExecutionOrder(netTxt); - CV_LOG_DEBUG(NULL, "DNN/TF: sortByExecutionOrder(config) => " << netTxt.node_size() << " nodes"); + CV_Assert(hasLayerAttr(layer, "squeeze_dims")); + const tensorflow::AttrValue& dims = getLayerAttr(layer, "squeeze_dims"); + std::vector dimsVector(dims.list().i_size()); + for (int i = 0; i < dimsVector.size(); ++i) + dimsVector[i] = dims.list().i(i); + + // Flatten layer can squeeze dimensions range into one. + std::sort(dimsVector.begin(), dimsVector.end()); + for (int i = 1; i < dimsVector.size(); ++i) + { + if (dimsVector[i] != dimsVector[i - 1] + 1) + CV_Error(Error::StsNotImplemented, "Unsupported squeeze configuration"); + } + int start = dimsVector.front() - 1, end = dimsVector.back(); + if (start == -1 && end == 0) // squeeze 0th dimension + { + start = 0; + end = 1; + } + layerParams.set("axis", start); + layerParams.set("end_axis", end); } - else + if (inpLayout == DATA_LAYOUT_NHWC) { - removePhaseSwitches(netBin); - CV_LOG_DEBUG(NULL, "DNN/TF: removePhaseSwitches(model) => " << netBin.node_size() << " nodes"); - - RemoveIdentityOps(netBin); - CV_LOG_DEBUG(NULL, "DNN/TF: RemoveIdentityOps(model) => " << netBin.node_size() << " nodes"); - - simplifySubgraphs(netBin); - CV_LOG_DEBUG(NULL, "DNN/TF: simplifySubgraphs(model) => " << netBin.node_size() << " nodes"); - sortByExecutionOrder(netBin); - CV_LOG_DEBUG(NULL, "DNN/TF: sortByExecutionOrder(model) => " << netBin.node_size() << " nodes"); + LayerParams permLP; + int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. + permLP.set("order", DictValue::arrayInt(order, 4)); + + std::string permName = name + "/nchw"; + CV_Assert(layer_id.find(permName) == layer_id.end()); + int permId = dstNet.addLayer(permName, "Permute", permLP); + layer_id[permName] = permId; + connect(layer_id, dstNet, inpId, permId, 0); + inpId = Pin(permName); } + int id = dstNet.addLayer(name, "Flatten", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, inpId, id, 0); + data_layouts[name] = DATA_LAYOUT_PLANAR; +} - tensorflow::GraphDef& net = netTxt.ByteSize() != 0 ? netTxt : netBin; - - int layersSize = net.node_size(); - - // Pre-fill data layouts where they are set explicitly. - // Assuming that nodes are in topological order - for (int i = layersSize - 1; i >= 0; --i) +void TFImporter::parseTranspose(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + Mat perm = getTensorContent(getConstBlob(layer, value_id, 1)); + CV_Assert(perm.type() == CV_32SC1); + int* permData = (int*)perm.data; + if (perm.total() == 4) { - const tensorflow::NodeDef& layer = net.node(i); - std::string name = layer.name(); - - CV_LOG_DEBUG(NULL, "DNN/TF: node(" << i << " - '" << name << "') propagating layout..."); - - try + // Only NHWC <-> NCHW permutations are allowed. OpenCV is always + // keep NCHW layout this way. + int inpLayout = getDataLayout(layer.input(0), data_layouts); + std::string type = "Identity"; + if (inpLayout == DATA_LAYOUT_NHWC) { - DataLayout layout = getDataLayout(layer); - std::map::iterator it = data_layouts.find(name); - if (it != data_layouts.end()) + if (permData[0] == 0 && permData[1] == 3 && permData[2] == 1 && permData[3] == 2) { - if (layout != DATA_LAYOUT_UNKNOWN) - { - if (it->second == DATA_LAYOUT_UNKNOWN) - it->second = layout; - else if (it->second != layout) - { - it->second = DATA_LAYOUT_UNKNOWN; - layout = DATA_LAYOUT_UNKNOWN; - } - } - else - layout = it->second; + // in TensorFlow: NHWC->NCHW + // in OpenCV: NCHW->NCHW + data_layouts[name] = DATA_LAYOUT_NCHW; } - else - data_layouts[name] = layout; - - // Specify input layers to have the same data layout. - for (int j = 0; j < layer.input_size(); ++j) + else if (permData[0] == 0 && permData[1] == 1 && permData[2] == 2 && permData[3] == 3) { - name = getNodeName(layer.input(j)); - it = data_layouts.find(name); - if (it != data_layouts.end()) - { - if (layout != DATA_LAYOUT_UNKNOWN) - { - if (it->second == DATA_LAYOUT_UNKNOWN) - it->second = layout; - else if (it->second != layout) - it->second = DATA_LAYOUT_UNKNOWN; - } - } - else - data_layouts[name] = layout; + // in TensorFlow: NHWC->NHWC + // in OpenCV: NCHW->NCHW + data_layouts[name] = DATA_LAYOUT_NHWC; + } + else if (permData[0] == 0 && permData[1] == 3 && permData[2] == 2 && permData[3] == 1) + { + // in TensorFlow: NHWC->NCWH + // in OpenCV: NCHW->NCWH + int permData[] = {0, 1, 3, 2}; + layerParams.set("order", DictValue::arrayInt(permData, perm.total())); + data_layouts[name] = DATA_LAYOUT_NCHW; // we keep track NCHW because channels position only matters + type = "Permute"; } + else + CV_Error(Error::StsParseError, "Only NHWC <-> NCHW permutations are allowed."); } - catch (const std::exception& e) + else if (inpLayout == DATA_LAYOUT_NCHW) { - CV_LOG_ERROR(NULL, "DNN/TF: Can't propagate layout for node='" << name << "'. Exception: " << e.what()); - throw; + if (permData[0] == 0 && permData[1] == 2 && permData[2] == 3 && permData[3] == 1) + { + // in TensorFlow: NCHW->NHWC + // in OpenCV: NCHW->NCHW + data_layouts[name] = DATA_LAYOUT_NHWC; + } + else if (permData[0] == 0 && permData[1] == 1 && permData[2] == 2 && permData[3] == 3) + { + // in TensorFlow: NCHW->NCHW + // in OpenCV: NCHW->NCHW + data_layouts[name] = DATA_LAYOUT_NCHW; + } + else + CV_Error(Error::StsParseError, "Only NHWC <-> NCHW permutations are allowed."); } + int id = dstNet.addLayer(name, type, layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); } - - addConstNodes(netBin, value_id, layers_to_ignore); - addConstNodes(netTxt, value_id, layers_to_ignore); - - - for (int li = 0; li < layersSize; li++) + else { - const tensorflow::NodeDef& layer = net.node(li); + layerParams.set("order", DictValue::arrayInt(permData, perm.total())); - const std::string name = layer.name(); - const std::string type = layer.op(); - const int ninputs = layer.input_size(); - CV_LOG_DEBUG(NULL, "DNN/TF: (" << li << "/" << layersSize << ") Parse layer " << name << " @ " << type << " with " << ninputs << " inputs"); + int id = dstNet.addLayer(name, "Permute", layerParams); + layer_id[name] = id; - parseNode(layer); + // one input only + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + data_layouts[name] = DATA_LAYOUT_UNKNOWN; } +} - for (size_t i = 0; i < netInputsNames.size(); i++) - { - CV_LOG_DEBUG(NULL, "DNN/TF: Model input: " << i << " - '" << netInputsNames[i] << "'"); - CV_Assert(!netInputsNames[i].empty()); - } - dstNet.setInputsNames(netInputsNames); - CV_LOG_DEBUG(NULL, "DNN/TF: ===================== Import completed ====================="); +void TFImporter::parseConstant(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ } -void TFImporter::addPermuteLayer(const int* order, const std::string& permName, Pin& inpId) +void TFImporter::parseLrn(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) { - LayerParams permLP; - permLP.set("order", DictValue::arrayInt(order, 4)); - CV_Assert(layer_id.find(permName) == layer_id.end()); - int permId = dstNet.addLayer(permName, "Permute", permLP); - layer_id[permName] = permId; - connect(layer_id, dstNet, inpId, permId, 0); - inpId = Pin(permName); + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + if(hasLayerAttr(layer, "alpha")) { + layerParams.set("alpha", getLayerAttr(layer, "alpha").f()); + } + if(hasLayerAttr(layer, "beta")) { + layerParams.set("beta", getLayerAttr(layer, "beta").f()); + } + if(hasLayerAttr(layer, "depth_radius")) { + int radius = (int)getLayerAttr(layer, "depth_radius").i(); + layerParams.set("local_size", 2*radius + 1); + } + if(hasLayerAttr(layer, "bias")) { + layerParams.set("bias", getLayerAttr(layer, "bias").f()); + } + layerParams.set("norm_by_size", false); + + int id = dstNet.addLayer(name, "LRN", layerParams); + layer_id[name] = id; + + connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); } -void TFImporter::parseNode(const tensorflow::NodeDef& layer_) +void TFImporter::parseConcat(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) { - tensorflow::NodeDef layer = layer_; + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); - tensorflow::GraphDef& net = netTxt.ByteSize() != 0 ? netTxt : netBin; + CV_CheckGT(num_inputs, 0, ""); + int axisId = (type == "Concat" ? 0 : num_inputs - 1); + int axis = getConstBlob(layer, value_id, axisId).int_val().Get(0); - /*const*/ std::string name = layer.name(); - /*const*/ std::string type = layer.op(); - /*const*/ int num_inputs = layer.input_size(); + if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) + axis = toNCHW(axis); + else if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NDHWC) + axis = toNCDHW(axis); + layerParams.set("axis", axis); - try - { - LayerParams layerParams; + // input(0) or input(n-1) is concat_dim + int from = (type == "Concat" ? 1 : 0); + int to = (type == "Concat" ? num_inputs : num_inputs - 1); - if (layers_to_ignore.find(name) != layers_to_ignore.end()) + for (int ii = from; ii < to; ii++) + { + Pin inp = parsePin(layer.input(ii)); + if (layer_id.find(inp.name) == layer_id.end()) { - CV_LOG_DEBUG(NULL, "DNN/TF: ignored"); - return; + // There are constant inputs. + LayerParams lp; + lp.name = inp.name; + lp.type = "Const"; + lp.blobs.resize(1); + blobFromTensor(getConstBlob(layer, value_id, ii), lp.blobs.back()); + CV_Assert_N(!lp.blobs[0].empty(), lp.blobs[0].type() == CV_32F); + + int constInpId = dstNet.addLayer(lp.name, lp.type, lp); + layer_id[lp.name] = constInpId; } + } - DataLayout predictedLayout = predictOutputDataLayout(layer); - data_layouts[name] = predictedLayout; + int id = dstNet.addLayer(name, "Concat", layerParams); + layer_id[name] = id; - if (type == "Conv2D" || type == "SpaceToBatchND" || type == "DepthwiseConv2dNative" || type == "Pad" || type == "MirrorPad" || type == "Conv3D") - { - CV_CheckGT(num_inputs, 0, ""); - // The first node of dilated convolution subgraph. - // Extract input node, dilation rate and paddings. - std::string input = layer.input(0); - StrIntVector next_layers; - if (type == "SpaceToBatchND" || type == "Pad") - { - next_layers = getNextLayers(net, name, "Conv2D"); - if (next_layers.empty()) - next_layers = getNextLayers(net, name, "DepthwiseConv2dNative"); - } + for (int ii = from; ii < to; ii++) + { + Pin inp = parsePin(layer.input(ii)); + if (layer_id.find(inp.name) == layer_id.end()) + CV_Error(Error::StsError, "Input layer not found: " + inp.name); + connect(layer_id, dstNet, inp, id, ii - from); + } +} - if (type == "SpaceToBatchND") - { - // op: "SpaceToBatchND" - // input: "input" - // input: "SpaceToBatchND/block_shape" - // input: "SpaceToBatchND/paddings" - CV_CheckEQ(num_inputs, 3, ""); +void TFImporter::parseMaxPool(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - DictValue dilation = parseDims(getConstBlob(layer, value_id, 1)); - CV_Assert(dilation.size() == 2); - layerParams.set("dilation_h", dilation.get(0)); - layerParams.set("dilation_w", dilation.get(1)); + CV_CheckGT(num_inputs, 0, ""); + layerParams.set("pool", "max"); - Mat paddings; - parseTensor(getConstBlob(layer, value_id, 2), paddings); + setKSize(layerParams, layer); + setStrides(layerParams, layer); + setPadding(layerParams, layer); + // Test_TensorFlow_nets.EAST_text_detection/1, NGRAPH/CPU + layerParams.set("ceil_mode", false); - // paddings is a 2x2 matrix: [[top, bot], [left, right]] - layerParams.set("pad_h", paddings.at(0)); - layerParams.set("pad_w", paddings.at(2)); + int id = dstNet.addLayer(name, "Pooling", layerParams); + layer_id[name] = id; - CV_Assert(next_layers.size() == 1); - layers_to_ignore.insert(next_layers[0].first); + connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); +} - // FIXIT don't override, rewrite this code - layer = net.node(next_layers[0].second); - name = layer.name(); - type = layer.op(); - num_inputs = layer.input_size(); - CV_LOG_DEBUG(NULL, "DNN/TF: switched to layer " << name << " @ " << type << ") with " << num_inputs << " inputs"); - } - else if (type == "Pad" || type == "MirrorPad") - { - Mat paddings = getTensorContent(getConstBlob(layer, value_id, 1)); - CV_Assert(paddings.type() == CV_32SC1); - if (paddings.total() == 8) - { - // Perhaps, we have NHWC padding dimensions order. - // N H W C - // 0 1 2 3 4 5 6 7 - std::swap(paddings.at(2), paddings.at(6)); - std::swap(paddings.at(3), paddings.at(7)); - // N C W H - // 0 1 2 3 4 5 6 7 - std::swap(paddings.at(4), paddings.at(6)); - std::swap(paddings.at(5), paddings.at(7)); - // N C H W - // 0 1 2 3 4 5 6 7 - } +void TFImporter::parseAvgPool(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - if (next_layers.empty() || paddings.total() != 8 || - paddings.at(4) != paddings.at(5) || - paddings.at(6) != paddings.at(7) || type == "MirrorPad") - { - // Just a single padding layer. - layerParams.set("paddings", DictValue::arrayInt((int*)paddings.data, paddings.total())); - if (type == "MirrorPad") - layerParams.set("type", "reflect"); + CV_CheckGT(num_inputs, 0, ""); + layerParams.set("pool", "ave"); + layerParams.set("ave_pool_padded_area", false); + setKSize(layerParams, layer); + setStrides(layerParams, layer); + setPadding(layerParams, layer); - int id = dstNet.addLayer(name, "Padding", layerParams); - layer_id[name] = id; + int id = dstNet.addLayer(name, "Pooling", layerParams); + layer_id[name] = id; - connect(layer_id, dstNet, parsePin(input), id, 0); - return; - } - else - { - // Merge with subsequent convolutional layer. - CV_Assert(next_layers.size() == 1); + connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); +} - layerParams.set("pad_h", paddings.at(4)); - layerParams.set("pad_w", paddings.at(6)); +void TFImporter::parseMaxPoolGrad(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - layers_to_ignore.insert(next_layers[0].first); + CV_CheckEQ(num_inputs, 3, ""); - // FIXIT don't override, rewrite this code - layer = net.node(next_layers[0].second); - name = layer.name(); - type = layer.op(); - num_inputs = layer.input_size(); - CV_LOG_DEBUG(NULL, "DNN/TF: switched to layer " << name << " @ " << type << ") with " << num_inputs << " inputs"); - } - } + layerParams.set("pool_k_h", 0); + layerParams.set("pool_k_w", 0); + layerParams.set("pool_stride_h", 0); + layerParams.set("pool_stride_w", 0); + layerParams.set("pool_pad_h", 0); + layerParams.set("pool_pad_w", 0); - // For the object detection networks, TensorFlow Object Detection API - // predicts deltas for bounding boxes in yxYX (ymin, xmin, ymax, xmax) - // order. We can manage it at DetectionOutput layer parsing predictions - // or shuffle last convolution's weights. - bool locPredTransposed = hasLayerAttr(layer, "loc_pred_transposed") && - getLayerAttr(layer, "loc_pred_transposed").b(); + int id = dstNet.addLayer(name, "MaxUnpool", layerParams); + layer_id[name] = id; - layerParams.set("bias_term", false); - layerParams.blobs.resize(1); + connect(layer_id, dstNet, parsePin(layer.input(2)), id, 0); + connect(layer_id, dstNet, parsePin(layer.input(1) + ":1"), id, 1); + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 2); +} - next_layers = getNextLayers(net, name, "BiasAdd"); - if (next_layers.size() == 1) { - layerParams.set("bias_term", true); - layerParams.blobs.resize(2); +void TFImporter::parsePlaceholder(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); - int weights_layer_index = next_layers[0].second; + DataLayout predictedLayout = data_layouts[name]; - blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]); - ExcludeLayer(net, weights_layer_index, 0, false); - layers_to_ignore.insert(next_layers[0].first); + if (!hasLayerAttr(layer, "dtype") || + getLayerAttr(layer, "dtype").type() != tensorflow::DT_BOOL) // If input is not a train/test flag. + { + netInputsNames.push_back(name); + layer_id[name] = 0; + } + tensorflow::TensorShapeProto shape; + if (hasLayerAttr(layer, "shape")) + shape = getLayerAttr(layer, "shape").shape(); + else if (hasLayerAttr(layer, "_output_shapes")) + { + tensorflow::AttrValue_ListValue list = getLayerAttr(layer, "_output_shapes").list(); + if (list.shape_size()) + shape = list.shape()[0]; + } + if (shape.dim_size()) + { + MatShape dims(shape.dim_size()); + for (int i = 0; i < dims.size(); ++i) + dims[i] = shape.dim(i).size(); + if (dims.size() == 4 && predictedLayout == DATA_LAYOUT_NHWC) + { + std::swap(dims[1], dims[3]); // NHWC->NCWH + std::swap(dims[2], dims[3]); // NCWH->NCHW + if (dims[0] == -1) // It's OK to have undetermined batch size + dims[0] = 1; + } + bool hasNeg = false; + for (int i = 0; i < dims.size() && !hasNeg; ++i) + { + hasNeg = dims[i] < 0; + } + if (!hasNeg) + netInputShapes.push_back(dims); + } +} - // Shuffle bias from yxYX to xyXY. - if (locPredTransposed) - { - const int numWeights = layerParams.blobs[1].total(); - float* biasData = reinterpret_cast(layerParams.blobs[1].data); - CV_Assert(numWeights % 4 == 0); - for (int i = 0; i < numWeights; i += 2) - { - std::swap(biasData[i], biasData[i + 1]); - } - } - } +void TFImporter::parseSplit(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // TODO: determining axis index remapping by input dimensions order of input blob + // TODO: slicing input may be Const op + // TODO: slicing kernels for convolutions - in current implementation it is impossible + // TODO: add parsing num of slices parameter + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckEQ(num_inputs, 2, ""); + // num_split + // 1st blob is dims tensor + int axis = getConstBlob(layer, value_id, 0).int_val().Get(0); + if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) + axis = toNCHW(axis); + layerParams.set("axis", axis); + + if (hasLayerAttr(layer, "num_split")) + layerParams.set("num_split", getLayerAttr(layer, "num_split").i()); + + int id = dstNet.addLayer(name, "Slice", layerParams); + layer_id[name] = id; + + // one input only + connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); +} - int kernelTensorInpId = -1; - const tensorflow::TensorProto& kernelTensor = getConstBlob(layer, value_id, -1, &kernelTensorInpId); - const String kernelTensorName = layer.input(kernelTensorInpId); - std::map::iterator sharedWeightsIt = sharedWeights.find(kernelTensorName); - if (sharedWeightsIt == sharedWeights.end()) - { - kernelFromTensor(kernelTensor, layerParams.blobs[0]); - releaseTensor(const_cast(&kernelTensor)); - - int* kshape = layerParams.blobs[0].size.p; - const int outCh = kshape[0]; - const int inCh = kshape[1]; - const int height = kshape[2]; - const int width = kshape[3]; - if (type == "DepthwiseConv2dNative") - { - CV_Assert(!locPredTransposed); - const int chMultiplier = kshape[0]; - - Mat copy = layerParams.blobs[0].clone(); - float* src = (float*)copy.data; - float* dst = (float*)layerParams.blobs[0].data; - for (int i = 0; i < chMultiplier; ++i) - for (int j = 0; j < inCh; ++j) - for (int s = 0; s < height * width; ++s) - { - int src_i = (i * inCh + j) * height * width + s; - int dst_i = (j * chMultiplier + i) * height* width + s; - dst[dst_i] = src[src_i]; - } - // TODO Use reshape instead - kshape[0] = inCh * chMultiplier; - kshape[1] = 1; - size_t* kstep = layerParams.blobs[0].step.p; - kstep[0] = kstep[1]; // fix steps too - } +void TFImporter::parseSlice(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "Slice" + // input: "input_node" + // input: "Slice/begin" + // input: "Slice/size" + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckEQ(num_inputs, 3, ""); + Mat begins = getTensorContent(getConstBlob(layer, value_id, 1)); + Mat sizes = getTensorContent(getConstBlob(layer, value_id, 2)); + CV_Assert_N(!begins.empty(), !sizes.empty()); + CV_CheckTypeEQ(begins.type(), CV_32SC1, ""); + CV_CheckTypeEQ(sizes.type(), CV_32SC1, ""); + + if (begins.total() == 4 && getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) + { + // Swap NHWC parameters' order to NCHW. + std::swap(*begins.ptr(0, 2), *begins.ptr(0, 3)); + std::swap(*begins.ptr(0, 1), *begins.ptr(0, 2)); + std::swap(*sizes.ptr(0, 2), *sizes.ptr(0, 3)); + std::swap(*sizes.ptr(0, 1), *sizes.ptr(0, 2)); + } + layerParams.set("begin", DictValue::arrayInt((int*)begins.data, begins.total())); + layerParams.set("size", DictValue::arrayInt((int*)sizes.data, sizes.total())); - // Shuffle output channels from yxYX to xyXY. - if (locPredTransposed) - { - const int slice = height * width * inCh; - for (int i = 0; i < outCh; i += 2) - { - cv::Mat src(1, slice, CV_32F, layerParams.blobs[0].ptr(i)); - cv::Mat dst(1, slice, CV_32F, layerParams.blobs[0].ptr(i + 1)); - std::swap_ranges(src.begin(), src.end(), dst.begin()); - } - } - sharedWeights[kernelTensorName] = layerParams.blobs[0]; - } - else - { - layerParams.blobs[0] = sharedWeightsIt->second; - } - Mat weights = layerParams.blobs[0]; - layerParams.set("kernel_size", DictValue::arrayInt(&weights.size[2], weights.dims - 2)); + int id = dstNet.addLayer(name, "Slice", layerParams); + layer_id[name] = id; - layerParams.set("num_output", layerParams.blobs[0].size[0]); + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); +} - setStrides(layerParams, layer); - if (!layerParams.has("pad_w") && !layerParams.has("pad_h")) - setPadding(layerParams, layer); +void TFImporter::parseStridedSlice(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckEQ(num_inputs, 4, ""); + Mat begins = getTensorContent(getConstBlob(layer, value_id, 1)); + Mat ends = getTensorContent(getConstBlob(layer, value_id, 2)); + Mat strides = getTensorContent(getConstBlob(layer, value_id, 3)); + CV_CheckTypeEQ(begins.type(), CV_32SC1, ""); + CV_CheckTypeEQ(ends.type(), CV_32SC1, ""); + CV_CheckTypeEQ(strides.type(), CV_32SC1, ""); + const int num = begins.total(); + CV_Assert_N(num == ends.total(), num == strides.total()); + + int end_mask = getLayerAttr(layer, "end_mask").i(); + for (int i = 0; i < num; ++i) + { + if (ends.at(i) < 0) + ends.at(i) -= 1; + if (end_mask & (1 << i)) + ends.at(i) = -1; + if (strides.at(i) != 1) + CV_Error(Error::StsNotImplemented, + format("StridedSlice with stride %d", strides.at(i))); + } + if (begins.total() == 4 && getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) + { + // Swap NHWC parameters' order to NCHW. + std::swap(begins.at(2), begins.at(3)); + std::swap(begins.at(1), begins.at(2)); + std::swap(ends.at(2), ends.at(3)); + std::swap(ends.at(1), ends.at(2)); + } + layerParams.set("begin", DictValue::arrayInt((int*)begins.data, begins.total())); + layerParams.set("end", DictValue::arrayInt((int*)ends.data, ends.total())); - // The final node of dilated convolution subgraph. - next_layers = getNextLayers(net, name, "BatchToSpaceND"); - if (!next_layers.empty()) - { - CV_Assert(next_layers.size() == 1); - ExcludeLayer(net, next_layers[0].second, 0, false); - layers_to_ignore.insert(next_layers[0].first); - } + int id = dstNet.addLayer(name, "Slice", layerParams); + layer_id[name] = id; - int id = dstNet.addLayer(name, "Convolution", layerParams); - layer_id[name] = id; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); +} - // one input only - connect(layer_id, dstNet, parsePin(input), id, 0); +void TFImporter::parseMul(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); + CV_CheckGT(num_inputs, 0, ""); + int constId = -1; + for(int ii = 0; ii < num_inputs; ++ii) + { + Pin input = parsePin(layer.input(ii)); + if (value_id.find(input.name) != value_id.end()) + { + constId = ii; + break; + } + } + CV_Assert((constId != -1) || (num_inputs == 2)); - if (getDataLayout(name, data_layouts) == DATA_LAYOUT_UNKNOWN) - data_layouts[name] = DATA_LAYOUT_NHWC; + if (constId != -1) + { + // Multiplication by constant. + CV_CheckEQ(num_inputs, 2, ""); + Mat scaleMat = getTensorContent(getConstBlob(layer, value_id)); + CV_Assert(scaleMat.type() == CV_32FC1); + if (type == "RealDiv") + { + if (constId == 0) + CV_Error(Error::StsNotImplemented, "Division of constant over variable"); + scaleMat = 1.0f / scaleMat; } - else if (type == "BiasAdd" || type == "Add" || type == "AddV2" || type == "Sub" || type=="AddN") + + int id; + if (scaleMat.total() == 1) // is a scalar. { - CV_CheckGT(num_inputs, 0, ""); - bool haveConst = false; - for(int ii = 0; !haveConst && ii < num_inputs; ++ii) + // Try to match with a LeakyRelu: + // node { + // name: "LeakyRelu/mul" + // op: "Mul" + // input: "LeakyRelu/alpha" + // input: "input" + // } + // node { + // name: "LeakyRelu/Maximum" + // op: "Maximum" + // input: "LeakyRelu/mul" + // input: "input" + // } + StrIntVector next_layers = getNextLayers(net, name, "Maximum"); + if (!next_layers.empty()) { - Pin input = parsePin(layer.input(ii)); - haveConst = value_id.find(input.name) != value_id.end(); - } - CV_Assert(!haveConst || num_inputs == 2); + int maximumLayerIdx = next_layers[0].second; - if (haveConst) - { - Mat values = getTensorContent(getConstBlob(layer, value_id)); - CV_Assert(values.type() == CV_32FC1); - if (type == "Sub") - values *= -1.0f; + CV_Assert(net.node(maximumLayerIdx).input_size() == 2); - int id; - if (values.total() == 1) // is a scalar. - { - layerParams.set("shift", values.at(0)); - id = dstNet.addLayer(name, "Power", layerParams); - } - else // is a vector - { - layerParams.blobs.resize(1, values); - id = dstNet.addLayer(name, "Shift", layerParams); - } - layer_id[name] = id; + // The input from the Mul layer can also be at index 1. + int mulInputIdx = (net.node(maximumLayerIdx).input(0) == name) ? 0 : 1; - // one input only - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + ExcludeLayer(net, maximumLayerIdx, mulInputIdx, false); + layers_to_ignore.insert(next_layers[0].first); + + layerParams.set("negative_slope", scaleMat.at(0)); + id = dstNet.addLayer(name, "ReLU", layerParams); } else { - layerParams.set("operation", "sum"); - if (type == "Sub") - { - static float subCoeffs[] = {1.f, -1.f}; - layerParams.set("coeff", DictValue::arrayReal(subCoeffs, 2)); - } - - int id = dstNet.addLayer(name, "Eltwise", layerParams); - layer_id[name] = id; - - for (int ii = 0; ii < num_inputs; ii++) - { - Pin inp = parsePin(layer.input(ii)); - if (layer_id.find(inp.name) == layer_id.end()) - CV_Error(Error::StsError, "Input layer not found: " + inp.name); - connect(layer_id, dstNet, inp, id, ii); - } + // Just a multiplication. + layerParams.set("scale", scaleMat.at(0)); + id = dstNet.addLayer(name, "Power", layerParams); } } - else if (type == "MatMul") + else // is a vector { - CV_CheckEQ(num_inputs, 2, ""); - - // For the object detection networks, TensorFlow Object Detection API - // predicts deltas for bounding boxes in yxYX (ymin, xmin, ymax, xmax) - // order. We can manage it at DetectionOutput layer parsing predictions - // or shuffle last Faster-RCNN's matmul weights. - bool locPredTransposed = hasLayerAttr(layer, "loc_pred_transposed") && - getLayerAttr(layer, "loc_pred_transposed").b(); + layerParams.blobs.resize(1, scaleMat); - layerParams.set("bias_term", false); - layerParams.blobs.resize(1); - - StrIntVector next_layers = getNextLayers(net, name, "BiasAdd"); // FIXIT Use layers fusion instead - if (next_layers.empty()) + StrIntVector next_layers = getNextLayers(net, name, "Add"); + if (!next_layers.empty()) { - next_layers = getNextLayers(net, name, "Add"); - } - if (next_layers.size() == 1) { layerParams.set("bias_term", true); layerParams.blobs.resize(2); int weights_layer_index = next_layers[0].second; - blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]); + blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs.back()); ExcludeLayer(net, weights_layer_index, 0, false); layers_to_ignore.insert(next_layers[0].first); - - if (locPredTransposed) - { - const int numWeights = layerParams.blobs[1].total(); - float* biasData = reinterpret_cast(layerParams.blobs[1].data); - CV_Assert(numWeights % 4 == 0); - for (int i = 0; i < numWeights; i += 2) - { - std::swap(biasData[i], biasData[i + 1]); - } - } - } - - int kernel_blob_index = -1; - const tensorflow::TensorProto& kernelTensor = getConstBlob(layer, value_id, -1, &kernel_blob_index); - const String kernelTensorName = layer.input(kernel_blob_index); - std::map::iterator sharedWeightsIt = sharedWeights.find(kernelTensorName); - if (sharedWeightsIt == sharedWeights.end()) - { - blobFromTensor(kernelTensor, layerParams.blobs[0]); - releaseTensor(const_cast(&kernelTensor)); - sharedWeights[kernelTensorName] = layerParams.blobs[0]; - } - else - { - layerParams.blobs[0] = sharedWeightsIt->second; } - if (kernel_blob_index == 1) { // In this case output is computed by x*W formula - W should be transposed - Mat data = layerParams.blobs[0].t(); - layerParams.blobs[0] = data.clone(); - } - - layerParams.set("num_output", layerParams.blobs[0].size[0]); - if (locPredTransposed) - { - CV_Assert(layerParams.blobs[0].dims == 2); - for (int i = 0; i < layerParams.blobs[0].size[0]; i += 2) - { - cv::Mat src = layerParams.blobs[0].row(i); - cv::Mat dst = layerParams.blobs[0].row(i + 1); - std::swap_ranges(src.begin(), src.end(), dst.begin()); - } - } - - int id = dstNet.addLayer(name, "InnerProduct", layerParams); - layer_id[name] = id; + if (hasLayerAttr(layer, "axis")) + layerParams.set("axis", getLayerAttr(layer, "axis").i()); - // one input only - int input_blob_index = kernel_blob_index == 0 ? 1 : 0; - connect(layer_id, dstNet, parsePin(layer.input(input_blob_index)), id, 0); - data_layouts[name] = DATA_LAYOUT_PLANAR; + id = dstNet.addLayer(name, "Scale", layerParams); } - else if (type == "Reshape") - { - CV_CheckGT(num_inputs, 0, ""); - Pin inpId = parsePin(layer.input(0)); - DataLayout inpLayout = getDataLayout(layer.input(0), data_layouts); - // There are two possible implementations: reshape an input using - // predefined sizes or use a second input blob as a source of new shape. - if (value_id.find(layer.input(1)) != value_id.end()) - { - Mat newShape = getTensorContent(getConstBlob(layer, value_id, 1)); - int newShapeSize = newShape.total(); - bool hasSwap = false; - if (newShapeSize == 4 && hasAllOnes(newShape, 0, 2)) - { - // NHWC->NCHW - std::swap(*newShape.ptr(0, 2), *newShape.ptr(0, 3)); - std::swap(*newShape.ptr(0, 1), *newShape.ptr(0, 2)); - hasSwap = true; - } - if (inpLayout == DATA_LAYOUT_NHWC) - { - if (newShapeSize >= 2 || newShape.at(1) == 1) - { - int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. - addPermuteLayer(order, name + "/nhwc", inpId); - if (newShapeSize < 4) - { - inpLayout = DATA_LAYOUT_NCHW; - } - else - { - inpLayout = DATA_LAYOUT_NHWC; - } - } - } - layerParams.set("dim", DictValue::arrayInt(newShape.ptr(), newShapeSize)); - - int id = dstNet.addLayer(name, "Reshape", layerParams); - layer_id[name] = id; + layer_id[name] = id; - // one input only - connect(layer_id, dstNet, inpId, id, 0); - inpId = Pin(name); + Pin inp0 = parsePin(layer.input(0)); + if (layer_id.find(inp0.name) != layer_id.end()) + // First operand is a constant. + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + else + connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); + } + else + { + // Check if all the inputs have the same shape. + bool equalInpShapes = true; + bool isShapeOnes = false; + MatShape outShape0; + for (int ii = 0; ii < num_inputs && !netInputShapes.empty(); ii++) + { + Pin pin = parsePin(layer.input(ii)); + int inpId = layer_id.find(pin.name)->second; - if ((inpLayout == DATA_LAYOUT_NHWC || inpLayout == DATA_LAYOUT_UNKNOWN || inpLayout == DATA_LAYOUT_PLANAR) && - newShapeSize == 4 && !hasSwap) - { - int order[] = {0, 3, 1, 2}; // Transform back to OpenCV's NCHW. - addPermuteLayer(order, name + "/nchw", inpId); - inpLayout = DATA_LAYOUT_NCHW; - } + // Get input shape + MatShape outShape; + std::vector inpShapes, outShapes; + dstNet.getLayerShapes(netInputShapes, inpId, inpShapes, outShapes); + CV_CheckGT(static_cast(outShapes.size()), pin.blobIndex, ""); + outShape = outShapes[pin.blobIndex]; - data_layouts[name] = newShapeSize == 2 ? DATA_LAYOUT_PLANAR : inpLayout; - } - else + if (ii == 0) { - int id = dstNet.addLayer(name, "Reshape", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, inpId, id, 0); - connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1); - data_layouts[name] = inpLayout; + outShape0 = outShape; } - } - else if (type == "Flatten" || type == "Squeeze") - { - CV_CheckGT(num_inputs, 0, ""); - Pin inpId = parsePin(layer.input(0)); - int inpLayout = getDataLayout(layer.input(0), data_layouts); - if (type == "Squeeze") + else if (outShape != outShape0) { - CV_Assert(hasLayerAttr(layer, "squeeze_dims")); - const tensorflow::AttrValue& dims = getLayerAttr(layer, "squeeze_dims"); - std::vector dimsVector(dims.list().i_size()); - for (int i = 0; i < dimsVector.size(); ++i) - dimsVector[i] = dims.list().i(i); - - // Flatten layer can squeeze dimensions range into one. - std::sort(dimsVector.begin(), dimsVector.end()); - for (int i = 1; i < dimsVector.size(); ++i) - { - if (dimsVector[i] != dimsVector[i - 1] + 1) - CV_Error(Error::StsNotImplemented, "Unsupported squeeze configuration"); - } - int start = dimsVector.front() - 1, end = dimsVector.back(); - if (start == -1 && end == 0) // squeeze 0th dimension - { - start = 0; - end = 1; - } - layerParams.set("axis", start); - layerParams.set("end_axis", end); + equalInpShapes = false; + isShapeOnes = isAllOnes(outShape, 2, outShape.size()) || + isAllOnes(outShape0, 2, outShape0.size()); + break; } - if (inpLayout == DATA_LAYOUT_NHWC) - { - LayerParams permLP; - int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. - permLP.set("order", DictValue::arrayInt(order, 4)); + } - std::string permName = name + "/nchw"; - CV_Assert(layer_id.find(permName) == layer_id.end()); - int permId = dstNet.addLayer(permName, "Permute", permLP); - layer_id[permName] = permId; - connect(layer_id, dstNet, inpId, permId, 0); - inpId = Pin(permName); - } - int id = dstNet.addLayer(name, "Flatten", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, inpId, id, 0); - data_layouts[name] = DATA_LAYOUT_PLANAR; + int id; + if (equalInpShapes || netInputShapes.empty() || (!equalInpShapes && isShapeOnes)) + { + layerParams.set("operation", type == "RealDiv" ? "div" : "prod"); + id = dstNet.addLayer(name, "Eltwise", layerParams); } - else if (type == "Transpose") + else { - CV_CheckGT(num_inputs, 0, ""); - Mat perm = getTensorContent(getConstBlob(layer, value_id, 1)); - CV_Assert(perm.type() == CV_32SC1); - int* permData = (int*)perm.data; - if (perm.total() == 4) - { - // Only NHWC <-> NCHW permutations are allowed. OpenCV is always - // keep NCHW layout this way. - int inpLayout = getDataLayout(layer.input(0), data_layouts); - std::string type = "Identity"; - if (inpLayout == DATA_LAYOUT_NHWC) - { - if (permData[0] == 0 && permData[1] == 3 && permData[2] == 1 && permData[3] == 2) - { - // in TensorFlow: NHWC->NCHW - // in OpenCV: NCHW->NCHW - data_layouts[name] = DATA_LAYOUT_NCHW; - } - else if (permData[0] == 0 && permData[1] == 1 && permData[2] == 2 && permData[3] == 3) - { - // in TensorFlow: NHWC->NHWC - // in OpenCV: NCHW->NCHW - data_layouts[name] = DATA_LAYOUT_NHWC; - } - else if (permData[0] == 0 && permData[1] == 3 && permData[2] == 2 && permData[3] == 1) - { - // in TensorFlow: NHWC->NCWH - // in OpenCV: NCHW->NCWH - int permData[] = {0, 1, 3, 2}; - layerParams.set("order", DictValue::arrayInt(permData, perm.total())); - data_layouts[name] = DATA_LAYOUT_NCHW; // we keep track NCHW because channels position only matters - type = "Permute"; - } - else - CV_Error(Error::StsParseError, "Only NHWC <-> NCHW permutations are allowed."); - } - else if (inpLayout == DATA_LAYOUT_NCHW) - { - if (permData[0] == 0 && permData[1] == 2 && permData[2] == 3 && permData[3] == 1) - { - // in TensorFlow: NCHW->NHWC - // in OpenCV: NCHW->NCHW - data_layouts[name] = DATA_LAYOUT_NHWC; - } - else if (permData[0] == 0 && permData[1] == 1 && permData[2] == 2 && permData[3] == 3) - { - // in TensorFlow: NCHW->NCHW - // in OpenCV: NCHW->NCHW - data_layouts[name] = DATA_LAYOUT_NCHW; - } - else - CV_Error(Error::StsParseError, "Only NHWC <-> NCHW permutations are allowed."); - } - int id = dstNet.addLayer(name, type, layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - } - else - { - layerParams.set("order", DictValue::arrayInt(permData, perm.total())); + if (type == "RealDiv") + CV_Error(Error::StsNotImplemented, "Division of non equal tensors"); + id = dstNet.addLayer(name, "Scale", layerParams); + } - int id = dstNet.addLayer(name, "Permute", layerParams); - layer_id[name] = id; + layer_id[name] = id; - // one input only - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - data_layouts[name] = DATA_LAYOUT_UNKNOWN; - } - } - else if (type == "Const") + for (int ii = 0; ii < num_inputs; ii++) { + Pin inp = parsePin(layer.input(ii)); + if (layer_id.find(inp.name) == layer_id.end()) + CV_Error(Error::StsError, "Input layer not found: " + inp.name); + connect(layer_id, dstNet, inp, id, ii); } - else if (type == "LRN") - { - CV_CheckGT(num_inputs, 0, ""); - if(hasLayerAttr(layer, "alpha")) { - layerParams.set("alpha", getLayerAttr(layer, "alpha").f()); - } - if(hasLayerAttr(layer, "beta")) { - layerParams.set("beta", getLayerAttr(layer, "beta").f()); - } - if(hasLayerAttr(layer, "depth_radius")) { - int radius = (int)getLayerAttr(layer, "depth_radius").i(); - layerParams.set("local_size", 2*radius + 1); - } - if(hasLayerAttr(layer, "bias")) { - layerParams.set("bias", getLayerAttr(layer, "bias").f()); - } - layerParams.set("norm_by_size", false); + } +} - int id = dstNet.addLayer(name, "LRN", layerParams); - layer_id[name] = id; +void TFImporter::parseFusedBatchNorm(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "FusedBatchNorm" + // input: "input" + // input: "BatchNorm/gamma" + // input: "BatchNorm/beta" + // input: "BatchNorm/moving_mean" + // input: "BatchNorm/moving_variance" - connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); - } - else if (type == "Concat" || type == "ConcatV2") - { - CV_CheckGT(num_inputs, 0, ""); - int axisId = (type == "Concat" ? 0 : num_inputs - 1); - int axis = getConstBlob(layer, value_id, axisId).int_val().Get(0); + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) - axis = toNCHW(axis); - else if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NDHWC) - axis = toNCDHW(axis); - layerParams.set("axis", axis); + CV_CheckEQ(num_inputs, 5, "Expected gamma, beta, mean and std"); + Pin inpId = parsePin(layer.input(0)); - // input(0) or input(n-1) is concat_dim - int from = (type == "Concat" ? 1 : 0); - int to = (type == "Concat" ? num_inputs : num_inputs - 1); + bool isTraining = hasLayerAttr(layer, "is_training") && getLayerAttr(layer, "is_training").b(); - for (int ii = from; ii < to; ii++) - { - Pin inp = parsePin(layer.input(ii)); - if (layer_id.find(inp.name) == layer_id.end()) - { - // There are constant inputs. - LayerParams lp; - lp.name = inp.name; - lp.type = "Const"; - lp.blobs.resize(1); - blobFromTensor(getConstBlob(layer, value_id, ii), lp.blobs.back()); - CV_Assert_N(!lp.blobs[0].empty(), lp.blobs[0].type() == CV_32F); - - int constInpId = dstNet.addLayer(lp.name, lp.type, lp); - layer_id[lp.name] = constInpId; - } - } + layerParams.blobs.resize(2); - int id = dstNet.addLayer(name, "Concat", layerParams); - layer_id[name] = id; + const tensorflow::TensorProto& gammaTensor = getConstBlob(layer, value_id, 1); + if (!gammaTensor.tensor_content().empty()) + { + layerParams.blobs.resize(layerParams.blobs.size() + 1); + layerParams.set("has_weight", true); + blobFromTensor(gammaTensor, layerParams.blobs.back()); + } + else + layerParams.set("has_weight", false); - for (int ii = from; ii < to; ii++) - { - Pin inp = parsePin(layer.input(ii)); - if (layer_id.find(inp.name) == layer_id.end()) - CV_Error(Error::StsError, "Input layer not found: " + inp.name); - connect(layer_id, dstNet, inp, id, ii - from); - } - } - else if (type == "MaxPool" || type == "MaxPool3D") - { - CV_CheckGT(num_inputs, 0, ""); - layerParams.set("pool", "max"); + const tensorflow::TensorProto& betaTensor = getConstBlob(layer, value_id, 2); + if (!betaTensor.tensor_content().empty()) + { + layerParams.blobs.resize(layerParams.blobs.size() + 1); + layerParams.set("has_bias", true); + blobFromTensor(betaTensor, layerParams.blobs.back()); + } + else + layerParams.set("has_bias", false); - setKSize(layerParams, layer); - setStrides(layerParams, layer); - setPadding(layerParams, layer); - // Test_TensorFlow_nets.EAST_text_detection/1, NGRAPH/CPU - layerParams.set("ceil_mode", false); + Mat mean, std; + if (isTraining) + { + if (layerParams.blobs.size() == 2) + CV_Error(Error::StsNotImplemented, "Cannot determine number " + "of parameters for batch normalization layer."); + mean = Mat::zeros(1, layerParams.blobs[2].total(), CV_32F); + std = Mat::ones(1, layerParams.blobs[2].total(), CV_32F); + + // Add an extra layer: Mean-Variance normalization + LayerParams mvnParams; + std::string mvnName = name + "/MVN"; + CV_Assert(layer_id.find(mvnName) == layer_id.end()); + int mvnId = dstNet.addLayer(mvnName, "MVN", mvnParams); + layer_id[mvnName] = mvnId; + connect(layer_id, dstNet, inpId, mvnId, 0); + inpId = Pin(mvnName); + } + else + { + blobFromTensor(getConstBlob(layer, value_id, 3), mean); + blobFromTensor(getConstBlob(layer, value_id, 4), std); + } + layerParams.blobs[0] = mean; + layerParams.blobs[1] = std; - int id = dstNet.addLayer(name, "Pooling", layerParams); - layer_id[name] = id; + if (hasLayerAttr(layer, "epsilon")) + layerParams.set("eps", getLayerAttr(layer, "epsilon").f()); - connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); - } - else if (type == "AvgPool" || type == "AvgPool3D") - { - CV_CheckGT(num_inputs, 0, ""); - layerParams.set("pool", "ave"); - layerParams.set("ave_pool_padded_area", false); - setKSize(layerParams, layer); - setStrides(layerParams, layer); - setPadding(layerParams, layer); + int id = dstNet.addLayer(name, "BatchNorm", layerParams); + layer_id[name] = id; - int id = dstNet.addLayer(name, "Pooling", layerParams); - layer_id[name] = id; + // one input only + connect(layer_id, dstNet, inpId, id, 0); +} - connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); - } - else if (type == "MaxPoolGrad") - { - CV_CheckEQ(num_inputs, 3, ""); +void TFImporter::parseConv2DBackpropInput(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "Conv2DBackpropInput" + // input: "conv2d_transpose/output_shape" + // input: "weights" + // input: "input" - layerParams.set("pool_k_h", 0); - layerParams.set("pool_k_w", 0); - layerParams.set("pool_stride_h", 0); - layerParams.set("pool_stride_w", 0); - layerParams.set("pool_pad_h", 0); - layerParams.set("pool_pad_w", 0); + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - int id = dstNet.addLayer(name, "MaxUnpool", layerParams); - layer_id[name] = id; + CV_CheckEQ(num_inputs, 3, "Expected output shape, weights and input nodes"); - connect(layer_id, dstNet, parsePin(layer.input(2)), id, 0); - connect(layer_id, dstNet, parsePin(layer.input(1) + ":1"), id, 1); - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 2); - } - else if (type == "Placeholder") + layerParams.set("bias_term", false); + layerParams.blobs.resize(1); + + StrIntVector next_layers = getNextLayers(net, name, "BiasAdd"); + if (next_layers.size() == 1) + { + layerParams.set("bias_term", true); + layerParams.blobs.resize(2); + + int weights_layer_index = next_layers[0].second; + + blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]); + ExcludeLayer(net, weights_layer_index, 0, false); + layers_to_ignore.insert(next_layers[0].first); + } + + kernelFromTensor(getConstBlob(layer, value_id, 1), layerParams.blobs[0]); + + const int* kshape = layerParams.blobs[0].size.p; + const int kernelH = kshape[2]; + const int kernelW = kshape[3]; + layerParams.set("kernel_h", kernelH); + layerParams.set("kernel_w", kernelW); + layerParams.set("num_output", kshape[1]); + + setStrides(layerParams, layer); + setPadding(layerParams, layer); + + // For convolution layer, output shape computes as + // o = 1 + (i - k + 2*p) / s + // i - input size, o - output size, k - kernel size, p - pad, s - stride + // In TensorFlow, p == 0 is padMode == 'VALID' or p == (k - 1) / 2 + // considering that k is odd. + // SAME: o = 1 + (i - 1) / s + // VALID: o = 1 + i / s + // Deconvolution's layer output shape computes as + // SAME: o = 1 + (i - 1)*s + // VALID: o = (i - 1)*s + // If output_shape differs from formulas above then adjust padding is applied. + + const int strideY = layerParams.get("stride_h"); + const int strideX = layerParams.get("stride_w"); + Mat outShape = getTensorContent(getConstBlob(layer, value_id, 0)); + const int outH = outShape.at(1); + const int outW = outShape.at(2); + if (layerParams.get("pad_mode") == "SAME") + { + layerParams.set("adj_w", (outW - 1) % strideX); + layerParams.set("adj_h", (outH - 1) % strideY); + } + else if (layerParams.get("pad_mode") == "VALID") + { + layerParams.set("adj_w", (outW - kernelW) % strideX); + layerParams.set("adj_h", (outH - kernelH) % strideY); + } + int id = dstNet.addLayer(name, "Deconvolution", layerParams); + layer_id[name] = id; + + // one input only + connect(layer_id, dstNet, parsePin(layer.input(2)), id, 0); +} + +void TFImporter::parseBlockLSTM(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "BlockLSTM" + // input: "lstm_block_wrapper/ToInt64/x" (ignore, number of time stamps) + // input: "input" + // input: "lstm_block_wrapper/zeros" (ignore) + // input: "lstm_block_wrapper/zeros" (ignore) + // input: "lstm_block_wrapper/kernel" + // input: "lstm_block_wrapper/w_i_diag" + // input: "lstm_block_wrapper/w_f_diag" + // input: "lstm_block_wrapper/w_o_diag" + // input: "lstm_block_wrapper/bias" + + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckEQ(num_inputs, 9, "Unexpected number of input nodes"); + + if (hasLayerAttr(layer, "forget_bias")) + layerParams.set("forget_bias", getLayerAttr(layer, "forget_bias").f()); + + if (hasLayerAttr(layer, "forget_bias")) + { + float cellClip = getLayerAttr(layer, "cell_clip").f(); + // Cell clip disabled if it's negative. + if (cellClip >= 0) { - if (!hasLayerAttr(layer, "dtype") || - getLayerAttr(layer, "dtype").type() != tensorflow::DT_BOOL) // If input is not a train/test flag. - { - netInputsNames.push_back(name); - layer_id[name] = 0; - } - tensorflow::TensorShapeProto shape; - if (hasLayerAttr(layer, "shape")) - shape = getLayerAttr(layer, "shape").shape(); - else if (hasLayerAttr(layer, "_output_shapes")) - { - tensorflow::AttrValue_ListValue list = getLayerAttr(layer, "_output_shapes").list(); - if (list.shape_size()) - shape = list.shape()[0]; - } - if (shape.dim_size()) - { - MatShape dims(shape.dim_size()); - for (int i = 0; i < dims.size(); ++i) - dims[i] = shape.dim(i).size(); - if (dims.size() == 4 && predictedLayout == DATA_LAYOUT_NHWC) - { - std::swap(dims[1], dims[3]); // NHWC->NCWH - std::swap(dims[2], dims[3]); // NCWH->NCHW - if (dims[0] == -1) // It's OK to have undetermined batch size - dims[0] = 1; - } - bool hasNeg = false; - for (int i = 0; i < dims.size() && !hasNeg; ++i) - { - hasNeg = dims[i] < 0; - } - if (!hasNeg) - netInputShapes.push_back(dims); - } + layerParams.set("use_cell_clip", true); + layerParams.set("cell_clip", cellClip); } - else if (type == "Split") { - // TODO: determining axis index remapping by input dimensions order of input blob - // TODO: slicing input may be Const op - // TODO: slicing kernels for convolutions - in current implementation it is impossible - // TODO: add parsing num of slices parameter - CV_CheckEQ(num_inputs, 2, ""); - // num_split - // 1st blob is dims tensor - int axis = getConstBlob(layer, value_id, 0).int_val().Get(0); - if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) - axis = toNCHW(axis); - layerParams.set("axis", axis); - - if (hasLayerAttr(layer, "num_split")) - layerParams.set("num_split", getLayerAttr(layer, "num_split").i()); - - int id = dstNet.addLayer(name, "Slice", layerParams); - layer_id[name] = id; + } - // one input only - connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); - } - else if (type == "Slice") + Mat W, Wh, Wx, b; + blobFromTensor(getConstBlob(layer, value_id, 4), W); + blobFromTensor(getConstBlob(layer, value_id, 8), b); + const int outSize = W.cols / 4; + + // IGFO->IFOG + float* weightData = (float*)W.data; + for (int i = 0; i < W.rows; ++i) + for (int j = 0; j < outSize; ++j) { - // op: "Slice" - // input: "input_node" - // input: "Slice/begin" - // input: "Slice/size" - CV_CheckEQ(num_inputs, 3, ""); - Mat begins = getTensorContent(getConstBlob(layer, value_id, 1)); - Mat sizes = getTensorContent(getConstBlob(layer, value_id, 2)); - CV_Assert_N(!begins.empty(), !sizes.empty()); - CV_CheckTypeEQ(begins.type(), CV_32SC1, ""); - CV_CheckTypeEQ(sizes.type(), CV_32SC1, ""); - - if (begins.total() == 4 && getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) - { - // Swap NHWC parameters' order to NCHW. - std::swap(*begins.ptr(0, 2), *begins.ptr(0, 3)); - std::swap(*begins.ptr(0, 1), *begins.ptr(0, 2)); - std::swap(*sizes.ptr(0, 2), *sizes.ptr(0, 3)); - std::swap(*sizes.ptr(0, 1), *sizes.ptr(0, 2)); - } - layerParams.set("begin", DictValue::arrayInt((int*)begins.data, begins.total())); - layerParams.set("size", DictValue::arrayInt((int*)sizes.data, sizes.total())); + std::swap(weightData[i * W.cols + 1 * outSize + j], + weightData[i * W.cols + 2 * outSize + j]); + std::swap(weightData[i * W.cols + 2 * outSize + j], + weightData[i * W.cols + 3 * outSize + j]); + } + Wx = W.rowRange(0, W.rows - outSize).t(); + Wh = W.rowRange(W.rows - outSize, W.rows).t(); - int id = dstNet.addLayer(name, "Slice", layerParams); - layer_id[name] = id; + layerParams.blobs.resize(3); + layerParams.blobs[0] = Wh; + layerParams.blobs[1] = Wx; + layerParams.blobs[2] = b; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - } - else if (type == "StridedSlice") + if (hasLayerAttr(layer, "use_peephole")) + { + bool usePeephole = getLayerAttr(layer, "use_peephole").b(); + if (usePeephole) { - CV_CheckEQ(num_inputs, 4, ""); - Mat begins = getTensorContent(getConstBlob(layer, value_id, 1)); - Mat ends = getTensorContent(getConstBlob(layer, value_id, 2)); - Mat strides = getTensorContent(getConstBlob(layer, value_id, 3)); - CV_CheckTypeEQ(begins.type(), CV_32SC1, ""); - CV_CheckTypeEQ(ends.type(), CV_32SC1, ""); - CV_CheckTypeEQ(strides.type(), CV_32SC1, ""); - const int num = begins.total(); - CV_Assert_N(num == ends.total(), num == strides.total()); - - int end_mask = getLayerAttr(layer, "end_mask").i(); - for (int i = 0; i < num; ++i) + layerParams.set("use_peephole", true); + layerParams.blobs.resize(6); + for (int i = 0; i < 3; ++i) { - if (ends.at(i) < 0) - ends.at(i) -= 1; - if (end_mask & (1 << i)) - ends.at(i) = -1; - if (strides.at(i) != 1) - CV_Error(Error::StsNotImplemented, - format("StridedSlice with stride %d", strides.at(i))); + Mat w; + blobFromTensor(getConstBlob(layer, value_id, 5 + i), w); + w = w.reshape(1, w.total()); // Single column. + w = Mat::diag(w); // Make a diagonal matrix. + layerParams.blobs[3 + i] = w; } - if (begins.total() == 4 && getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) - { - // Swap NHWC parameters' order to NCHW. - std::swap(begins.at(2), begins.at(3)); - std::swap(begins.at(1), begins.at(2)); - std::swap(ends.at(2), ends.at(3)); - std::swap(ends.at(1), ends.at(2)); - } - layerParams.set("begin", DictValue::arrayInt((int*)begins.data, begins.total())); - layerParams.set("end", DictValue::arrayInt((int*)ends.data, ends.total())); + } + } - int id = dstNet.addLayer(name, "Slice", layerParams); - layer_id[name] = id; + int id = dstNet.addLayer(name, "LSTM", layerParams); + layer_id[name] = id; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - } - else if (type == "Mul" || type == "RealDiv") - { - CV_CheckGT(num_inputs, 0, ""); - int constId = -1; - for(int ii = 0; ii < num_inputs; ++ii) - { - Pin input = parsePin(layer.input(ii)); - if (value_id.find(input.name) != value_id.end()) - { - constId = ii; - break; - } - } - CV_Assert((constId != -1) || (num_inputs == 2)); + // one input only + connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); + data_layouts[name] = DATA_LAYOUT_UNKNOWN; +} - if (constId != -1) - { - // Multiplication by constant. - CV_CheckEQ(num_inputs, 2, ""); - Mat scaleMat = getTensorContent(getConstBlob(layer, value_id)); - CV_Assert(scaleMat.type() == CV_32FC1); - if (type == "RealDiv") - { - if (constId == 0) - CV_Error(Error::StsNotImplemented, "Division of constant over variable"); - scaleMat = 1.0f / scaleMat; - } +void TFImporter::parseResize(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer_, LayerParams& layerParams) +{ + tensorflow::NodeDef layer = layer_; + std::string name = layer.name(); + const std::string& type = layer.op(); + int num_inputs = layer.input_size(); - int id; - if (scaleMat.total() == 1) // is a scalar. - { - // Try to match with a LeakyRelu: - // node { - // name: "LeakyRelu/mul" - // op: "Mul" - // input: "LeakyRelu/alpha" - // input: "input" - // } - // node { - // name: "LeakyRelu/Maximum" - // op: "Maximum" - // input: "LeakyRelu/mul" - // input: "input" - // } - StrIntVector next_layers = getNextLayers(net, name, "Maximum"); - if (!next_layers.empty()) - { - int maximumLayerIdx = next_layers[0].second; + CV_CheckGT(num_inputs, 0, ""); + std::string convWeights = ""; + if (type == "FusedResizeAndPadConv2D") + { + // input: "mul_1" + // input: "decoder/ResizeBilinear/size" + // input: "decoder/decoder_conv0/Conv2D_dummy_paddings" + // input: "decoder/decoder_conv0/weights" + CV_CheckEQ(num_inputs, 4, "Number of input for FusedResizeAndPadConv2D"); - CV_Assert(net.node(maximumLayerIdx).input_size() == 2); + Mat paddings = getTensorContent(getConstBlob(layer, value_id, 2)); + CV_CheckEQ(countNonZero(paddings), 0, "Unsupported mode"); - // The input from the Mul layer can also be at index 1. - int mulInputIdx = (net.node(maximumLayerIdx).input(0) == name) ? 0 : 1; + convWeights = layer.input(3); + layer.mutable_input()->DeleteSubrange(2, 2); // FIXIT do NOT modify input model + num_inputs = layer.input_size(); + name = name + "/resize"; - ExcludeLayer(net, maximumLayerIdx, mulInputIdx, false); - layers_to_ignore.insert(next_layers[0].first); + if (hasLayerAttr(layer, "resize_align_corners")) + { + // FIXIT do NOT modify input model + layer.mutable_attr()->insert( + ::google::protobuf::MapPair("align_corners", + getLayerAttr(layer, "resize_align_corners"))); + } + } + if (num_inputs == 2) + { + Mat outSize = getTensorContent(getConstBlob(layer, value_id, 1)); + CV_CheckTypeEQ(outSize.type(), CV_32SC1, ""); CV_CheckEQ(outSize.total(), (size_t)2, ""); + layerParams.set("height", outSize.at(0, 0)); + layerParams.set("width", outSize.at(0, 1)); + } + else if (num_inputs == 3) + { + Mat factorHeight = getTensorContent(getConstBlob(layer, value_id, 1)); + Mat factorWidth = getTensorContent(getConstBlob(layer, value_id, 2)); + factorHeight.convertTo(factorHeight, CV_32F); + factorWidth.convertTo(factorWidth, CV_32F); + layerParams.set("zoom_factor_x", factorWidth.at(0)); + layerParams.set("zoom_factor_y", factorHeight.at(0)); + } + else + CV_Check(num_inputs, num_inputs == 2 || num_inputs == 3, ""); - layerParams.set("negative_slope", scaleMat.at(0)); - id = dstNet.addLayer(name, "ReLU", layerParams); - } - else - { - // Just a multiplication. - layerParams.set("scale", scaleMat.at(0)); - id = dstNet.addLayer(name, "Power", layerParams); - } - } - else // is a vector - { - layerParams.blobs.resize(1, scaleMat); - - StrIntVector next_layers = getNextLayers(net, name, "Add"); - if (!next_layers.empty()) - { - layerParams.set("bias_term", true); - layerParams.blobs.resize(2); - - int weights_layer_index = next_layers[0].second; - blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs.back()); - ExcludeLayer(net, weights_layer_index, 0, false); - layers_to_ignore.insert(next_layers[0].first); - } + if (type == "ResizeNearestNeighbor") + layerParams.set("interpolation", "nearest"); + else + layerParams.set("interpolation", "bilinear"); - if (hasLayerAttr(layer, "axis")) - layerParams.set("axis", getLayerAttr(layer, "axis").i()); + if (hasLayerAttr(layer, "align_corners")) + layerParams.set("align_corners", getLayerAttr(layer, "align_corners").b()); - id = dstNet.addLayer(name, "Scale", layerParams); - } - layer_id[name] = id; + if (hasLayerAttr(layer, "half_pixel_centers")) + layerParams.set("half_pixel_centers", getLayerAttr(layer, "half_pixel_centers").b()); - Pin inp0 = parsePin(layer.input(0)); - if (layer_id.find(inp0.name) != layer_id.end()) - // First operand is a constant. - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - else - connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); - } - else - { - // Check if all the inputs have the same shape. - bool equalInpShapes = true; - bool isShapeOnes = false; - MatShape outShape0; - for (int ii = 0; ii < num_inputs && !netInputShapes.empty(); ii++) - { - Pin pin = parsePin(layer.input(ii)); - int inpId = layer_id.find(pin.name)->second; + int id = dstNet.addLayer(name, "Resize", layerParams); + layer_id[name] = id; - // Get input shape - MatShape outShape; - std::vector inpShapes, outShapes; - dstNet.getLayerShapes(netInputShapes, inpId, inpShapes, outShapes); - CV_CheckGT(static_cast(outShapes.size()), pin.blobIndex, ""); - outShape = outShapes[pin.blobIndex]; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - if (ii == 0) - { - outShape0 = outShape; - } - else if (outShape != outShape0) - { - equalInpShapes = false; - isShapeOnes = isAllOnes(outShape, 2, outShape.size()) || - isAllOnes(outShape0, 2, outShape0.size()); - break; - } - } + // Step back to add convolution + if (type == "FusedResizeAndPadConv2D") + { + tensorflow::NodeDef conv = layer_; + conv.clear_input(); + conv.add_input(name); + conv.add_input(convWeights); + conv.set_op("Conv2D"); + parseNode(conv); + } +} - int id; - if (equalInpShapes || netInputShapes.empty() || (!equalInpShapes && isShapeOnes)) - { - layerParams.set("operation", type == "RealDiv" ? "div" : "prod"); - id = dstNet.addLayer(name, "Eltwise", layerParams); - } - else - { - if (type == "RealDiv") - CV_Error(Error::StsNotImplemented, "Division of non equal tensors"); - id = dstNet.addLayer(name, "Scale", layerParams); - } +void TFImporter::parseL2Normalize(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "L2Normalize" + // input: "input" + // input: "reduction_indices" (axis) - layer_id[name] = id; + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); - for (int ii = 0; ii < num_inputs; ii++) - { - Pin inp = parsePin(layer.input(ii)); - if (layer_id.find(inp.name) == layer_id.end()) - CV_Error(Error::StsError, "Input layer not found: " + inp.name); - connect(layer_id, dstNet, inp, id, ii); - } + CV_CheckEQ(num_inputs, 2, ""); + Mat reductionIndices = getTensorContent(getConstBlob(layer, value_id, 1)); + CV_Assert(reductionIndices.type() == CV_32SC1); + + const int numAxes = reductionIndices.total(); + if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) + for (int i = 0; i < numAxes; ++i) + reductionIndices.at(i) = toNCHW(reductionIndices.at(i)); + + cv::sort(reductionIndices, reductionIndices, SORT_ASCENDING); + for (int i = 1; i < numAxes; ++i) + { + CV_Assert(reductionIndices.at(i) == reductionIndices.at(i - 1) + 1); + // Axes have the same sign. + CV_Assert(reductionIndices.at(i) * reductionIndices.at(i - 1) >= 0); + } + layerParams.set("start_axis", reductionIndices.at(0)); + layerParams.set("end_axis", reductionIndices.at(numAxes - 1)); + + int id = dstNet.addLayer(name, "Normalize", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); +} + +void TFImporter::parsePriorBox(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckEQ(num_inputs, 2, ""); + if (hasLayerAttr(layer, "min_size")) + layerParams.set("min_size", getLayerAttr(layer, "min_size").i()); + if (hasLayerAttr(layer, "max_size")) + layerParams.set("max_size", getLayerAttr(layer, "max_size").i()); + if (hasLayerAttr(layer, "flip")) + layerParams.set("flip", getLayerAttr(layer, "flip").b()); + if (hasLayerAttr(layer, "clip")) + layerParams.set("clip", getLayerAttr(layer, "clip").b()); + if (hasLayerAttr(layer, "offset")) + layerParams.set("offset", getLayerAttr(layer, "offset").f()); + if (hasLayerAttr(layer, "step")) + layerParams.set("step", getLayerAttr(layer, "step").f()); + + const std::string paramNames[] = {"variance", "aspect_ratio", "scales", + "width", "height"}; + for (int i = 0; i < 5; ++i) + { + if (hasLayerAttr(layer, paramNames[i])) + { + Mat values = getTensorContent(getLayerAttr(layer, paramNames[i]).tensor()); + layerParams.set(paramNames[i], + DictValue::arrayReal((float*)values.data, values.total())); + } + } + int id = dstNet.addLayer(name, "PriorBox", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1); + data_layouts[name] = DATA_LAYOUT_UNKNOWN; +} + +void TFImporter::parseSoftmax(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + if (hasLayerAttr(layer, "axis")) + layerParams.set("axis", getLayerAttr(layer, "axis").i()); + + int id = dstNet.addLayer(name, "Softmax", layerParams); + layer_id[name] = id; + connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); +} + +void TFImporter::parseCropAndResize(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "CropAndResize" + // input: "input" + // input: "boxes" + // input: "sizes" + + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + CV_CheckEQ(num_inputs, 3, ""); + + Mat cropSize = getTensorContent(getConstBlob(layer, value_id, 2)); + CV_CheckTypeEQ(cropSize.type(), CV_32SC1, ""); CV_CheckEQ(cropSize.total(), (size_t)2, ""); + + layerParams.set("height", cropSize.at(0)); + layerParams.set("width", cropSize.at(1)); + + int id = dstNet.addLayer(name, "CropAndResize", layerParams); + layer_id[name] = id; + + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1); +} + +void TFImporter::parseMean(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // Computes the mean of elements across dimensions of a tensor. + // If keepdims is false (default) reduces input_tensor along the dimensions given in axis, + // else the reduced dimensions are retained with length 1. + // if indices = [1, 2] in NHWC layout we use global pooling: NxCxHxW --Pooling--> NxCx1x1 + // if keepdims is false we use Flatten after Pooling: out_shape = NxC + // if indices = [0] we use a global pooling by indices. + // To return correct shape, we use Reshape after Pooling. To determine input shape use Slice for input, + // if keepdims is false we use Flatten after Slice. + // Example: input_shape = NxCxHxW + // determine out shape: NxCxHxW --Slice--> 1xCxHxW + // out_shape = 1xCxHxW if keepDims else (1xCxHxW --Flatten--> CxHxW) + // global pool: NxCxHxW --Flatten--> Nx(C*H*W) --Reshape--> 1x1xNx(C*H*W) --Pooling--> 1x1x1x(C*H*W) --Reshape--> out_shape + + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + + Mat indices = getTensorContent(getConstBlob(layer, value_id, 1)); + CV_Assert(indices.type() == CV_32SC1); + + // There are two attributes, "keepdims" and a deprecated "keep_dims". + bool keepDims = false; + if (hasLayerAttr(layer, "keepdims")) + keepDims = getLayerAttr(layer, "keepdims").b(); + else if (hasLayerAttr(layer, "keep_dims")) + keepDims = getLayerAttr(layer, "keep_dims").b(); + + if (indices.total() == 1 && indices.at(0) == 0) + { + LayerParams flattenLp; + std::string flattenName = name + "/flatten"; + CV_Assert(layer_id.find(flattenName) == layer_id.end()); + int flattenId = dstNet.addLayer(flattenName, "Flatten", flattenLp); + layer_id[flattenName] = flattenId; + connect(layer_id, dstNet, parsePin(layer.input(0)), flattenId, 0); + + LayerParams reshapeLp; + std::string reshapeName = name + "/reshape"; + CV_Assert(layer_id.find(reshapeName) == layer_id.end()); + reshapeLp.set("axis", 0); + reshapeLp.set("num_axes", 1); + int newShape[] = {1, 1, -1}; + reshapeLp.set("dim", DictValue::arrayInt(&newShape[0], 3)); + + int reshapeId = dstNet.addLayer(reshapeName, "Reshape", reshapeLp); + layer_id[reshapeName] = reshapeId; + connect(layer_id, dstNet, Pin(flattenName), reshapeId, 0); + + LayerParams avgLp; + std::string avgName = name + "/avg"; + CV_Assert(layer_id.find(avgName) == layer_id.end()); + avgLp.set("pool", type == "Mean" ? "ave" : "sum"); + // pooling kernel H x 1 + avgLp.set("global_pooling_h", true); + avgLp.set("kernel_w", 1); + int avgId = dstNet.addLayer(avgName, "Pooling", avgLp); + layer_id[avgName] = avgId; + connect(layer_id, dstNet, Pin(reshapeName), avgId, 0); + + LayerParams sliceLp; + std::string layerShapeName = name + "/slice"; + CV_Assert(layer_id.find(layerShapeName) == layer_id.end()); + sliceLp.set("axis", 0); + int begin[] = {0}; + int size[] = {1}; + sliceLp.set("begin", DictValue::arrayInt(&begin[0], 1)); + sliceLp.set("size", DictValue::arrayInt(&size[0], 1)); + int sliceId = dstNet.addLayer(layerShapeName, "Slice", sliceLp); + layer_id[layerShapeName] = sliceId; + connect(layer_id, dstNet, Pin(layer.input(0)), sliceId, 0); + + if (!keepDims) + { + LayerParams squeezeLp; + std::string squeezeName = name + "/squeeze"; + CV_Assert(layer_id.find(squeezeName) == layer_id.end()); + squeezeLp.set("axis", 0); + squeezeLp.set("end_axis", 1); + int squeezeId = dstNet.addLayer(squeezeName, "Flatten", squeezeLp); + layer_id[squeezeName] = squeezeId; + connect(layer_id, dstNet, Pin(layerShapeName), squeezeId, 0); + layerShapeName = squeezeName; + } + + int id = dstNet.addLayer(name, "Reshape", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, Pin(avgName), id, 0); + connect(layer_id, dstNet, Pin(layerShapeName), id, 1); + } else if (indices.total() == 1) { + int axis = toNCHW(indices.at(0)); + if (axis == 2 || axis == 3) + { + layerParams.set("pool", type == "Mean" ? "ave" : "sum"); + layerParams.set(axis == 2 ? "kernel_w" : "kernel_h", 1); + layerParams.set(axis == 2 ? "global_pooling_h" : "global_pooling_w", true); + int id = dstNet.addLayer(name, "Pooling", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + + if (!keepDims) + { + // To keep correct order after squeeze dims we first need to change layout from NCHW to NHWC + LayerParams permLP; + int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. + std::string permName = name + "/nchw"; + Pin inpId = Pin(name); + addPermuteLayer(order, permName, inpId); + + LayerParams squeezeLp; + std::string squeezeName = name + "/squeeze"; + CV_Assert(layer_id.find(squeezeName) == layer_id.end()); + squeezeLp.set("axis", indices.at(0)); + squeezeLp.set("end_axis", indices.at(0) + 1); + int squeezeId = dstNet.addLayer(squeezeName, "Flatten", squeezeLp); + layer_id[squeezeName] = squeezeId; + connect(layer_id, dstNet, Pin(permName), squeezeId, 0); } } - else if (type == "FusedBatchNorm" || type == "FusedBatchNormV3") + else if (axis == 1) { - // op: "FusedBatchNorm" - // input: "input" - // input: "BatchNorm/gamma" - // input: "BatchNorm/beta" - // input: "BatchNorm/moving_mean" - // input: "BatchNorm/moving_variance" - CV_CheckEQ(num_inputs, 5, "Expected gamma, beta, mean and std"); + int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. Pin inpId = parsePin(layer.input(0)); + addPermuteLayer(order, name + "/nhwc", inpId); - bool isTraining = hasLayerAttr(layer, "is_training") && getLayerAttr(layer, "is_training").b(); - - layerParams.blobs.resize(2); + layerParams.set("pool", type == "Mean" ? "ave" : "sum"); + layerParams.set("kernel_h", 1); + layerParams.set("global_pooling_w", true); + int id = dstNet.addLayer(name, "Pooling", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, inpId, id, 0); - const tensorflow::TensorProto& gammaTensor = getConstBlob(layer, value_id, 1); - if (!gammaTensor.tensor_content().empty()) + if (!keepDims) { - layerParams.blobs.resize(layerParams.blobs.size() + 1); - layerParams.set("has_weight", true); - blobFromTensor(gammaTensor, layerParams.blobs.back()); + LayerParams squeezeLp; + std::string squeezeName = name + "/squeeze"; + CV_Assert(layer_id.find(squeezeName) == layer_id.end()); + int channel_id = 3; // TF NHWC layout + squeezeLp.set("axis", channel_id - 1); + squeezeLp.set("end_axis", channel_id); + int squeezeId = dstNet.addLayer(squeezeName, "Flatten", squeezeLp); + layer_id[squeezeName] = squeezeId; + connect(layer_id, dstNet, Pin(name), squeezeId, 0); } else - layerParams.set("has_weight", false); + { + int order[] = {0, 3, 1, 2}; // From NHWC to OpenCV's NCHW. + Pin inpId = parsePin(name); + addPermuteLayer(order, name + "/nchw", inpId); + } + } + } else { + if (indices.total() != 2 || indices.at(0) != 1 || indices.at(1) != 2) + CV_Error(Error::StsNotImplemented, "Unsupported mode of reduce_mean or reduce_sum operation."); + + layerParams.set("pool", type == "Mean" ? "ave" : "sum"); + layerParams.set("global_pooling", true); + int id = dstNet.addLayer(name, "Pooling", layerParams); + layer_id[name] = id; + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + + if (!keepDims) + { + LayerParams flattenLp; + std::string flattenName = name + "/flatten"; + CV_Assert(layer_id.find(flattenName) == layer_id.end()); + int flattenId = dstNet.addLayer(flattenName, "Flatten", flattenLp); + layer_id[flattenName] = flattenId; + connect(layer_id, dstNet, Pin(name), flattenId, 0); + } + } +} + +void TFImporter::parsePack(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: tf.stack(list of tensors, axis=0) + // Join a list of inputs along a new axis. + // The "axis" specifies the index of the new axis in the dimensions of the output. + // Example: given a list with "N" tensors of shape (C, H, W): + // if axis == 0 then the output tensor will have the shape (N, C, H, W), + // if axis == 1 then the output tensor will have the shape (C, N, H, W). + + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + CV_Assert(hasLayerAttr(layer, "axis")); + int dim = (int)getLayerAttr(layer, "axis").i(); + if (dim != 0) + CV_Error(Error::StsNotImplemented, "Unsupported mode of pack operation."); + + CV_Assert(hasLayerAttr(layer, "N")); + int num = (int)getLayerAttr(layer, "N").i(); + CV_CheckEQ(num_inputs, num, ""); + std::string base_name = name + "/reshape_"; + std::vector reshape_ids; + for (int i = 0; i < num; i++) { + std::ostringstream ss; + ss << i; + std::string reshape_name = base_name + ss.str(); + LayerParams reshapeLP; + reshapeLP.set("axis", dim); + reshapeLP.set("num_axes", 1); + int outShape[] = {1, -1}; + reshapeLP.set("dim", DictValue::arrayInt(&outShape[0], 2)); + int id = dstNet.addLayer(reshape_name, "Reshape", reshapeLP); + layer_id[reshape_name] = id; + reshape_ids.push_back(id); + connect(layer_id, dstNet, parsePin(layer.input(i)), id, 0); + } + + layerParams.set("axis", dim); + int id = dstNet.addLayer(name, "Concat", layerParams); + layer_id[name] = id; + + for (int li = 0; li < num; li++) + dstNet.connect(reshape_ids[li], 0, id, li); +} + +void TFImporter::parseClipByValue(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // op: "ClipByValue" + // input: "input" + // input: "mix" + // input: "max" + + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckEQ(num_inputs, 3, ""); + + Mat minValue = getTensorContent(getConstBlob(layer, value_id, 1)); + Mat maxValue = getTensorContent(getConstBlob(layer, value_id, 2)); + CV_CheckEQ(minValue.total(), (size_t)1, ""); CV_CheckTypeEQ(minValue.type(), CV_32FC1, ""); + CV_CheckEQ(maxValue.total(), (size_t)1, ""); CV_CheckTypeEQ(maxValue.type(), CV_32FC1, ""); + + layerParams.set("min_value", minValue.at(0)); + layerParams.set("max_value", maxValue.at(0)); + + int id = dstNet.addLayer(name, "ReLU6", layerParams); + layer_id[name] = id; + + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); +} + +void TFImporter::parseLeakyRelu(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + CV_Assert(hasLayerAttr(layer, "alpha")); + layerParams.set("negative_slope", getLayerAttr(layer, "alpha").f()); + + int id = dstNet.addLayer(name, "ReLU", layerParams); + layer_id[name] = id; + connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); +} + +void TFImporter::parseActivation(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); + + CV_CheckGT(num_inputs, 0, ""); + std::string dnnType = type; + if (type == "Abs") dnnType = "AbsVal"; + else if (type == "Tanh") dnnType = "TanH"; + else if (type == "Relu") dnnType = "ReLU"; + else if (type == "Relu6") dnnType = "ReLU6"; + else if (type == "Elu") dnnType = "ELU"; + + int id = dstNet.addLayer(name, dnnType, layerParams); + layer_id[name] = id; + connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); +} + +void TFImporter::parseCustomLayer(tensorflow::GraphDef& net, const tensorflow::NodeDef& layer, LayerParams& layerParams) +{ + // Importer does not know how to map this TensorFlow's operation onto OpenCV's layer. + // However we create a layer with the same type and rely that user defined a custom layer. + + const std::string& name = layer.name(); + const std::string& type = layer.op(); + const int num_inputs = layer.input_size(); + + // All the attributes are added to LayerParams. + google::protobuf::Map attr = layer.attr(); + for (google::protobuf::Map::const_iterator ai = attr.begin(); + ai != attr.end(); ++ai) + { + if (ai->second.value_case() == tensorflow::AttrValue::kS) // string + layerParams.set(ai->first, ai->second.s()); + if (ai->second.value_case() == tensorflow::AttrValue::kI) // int64 + layerParams.set(ai->first, ai->second.i()); + if (ai->second.value_case() == tensorflow::AttrValue::kF) // float + layerParams.set(ai->first, ai->second.f()); + if (ai->second.value_case() == tensorflow::AttrValue::kB) // bool + layerParams.set(ai->first, ai->second.b()); + } + + // All the Const input nodes are added to layer's blobs. + std::vector inputsNames; + for (int i = 0; i < num_inputs; ++i) + { + // Check if input is a Const node. + if (value_id.find(layer.input(i)) != value_id.end()) + { + Mat blob = getTensorContent(getConstBlob(layer, value_id, i)); + layerParams.blobs.push_back(blob); + } + else + inputsNames.push_back(layer.input(i)); + } + int id = dstNet.addLayer(name, type, layerParams); + layer_id[name] = id; + + for (int i = 0; i < inputsNames.size(); ++i) + { + connect(layer_id, dstNet, parsePin(inputsNames[i]), id, i); + } +} + +TFImporter::TFImporter(Net& net, const char *model, const char *config) + : utilNet(DNN_DIAGNOSTICS_RUN ? new Net : nullptr), + dstNet(DNN_DIAGNOSTICS_RUN ? *utilNet : net), dispatch(buildDispatchMap()) +{ + if (model && model[0]) + { + CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow model from file: " << model); + ReadTFNetParamsFromBinaryFileOrDie(model, &netBin); + } + if (config && config[0]) + { + CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow config from file: " << config); + ReadTFNetParamsFromTextFileOrDie(config, &netTxt); + } + + populateNet(); +} + +TFImporter::TFImporter( + Net& net, + const char *dataModel, size_t lenModel, + const char *dataConfig, size_t lenConfig +) + : utilNet(DNN_DIAGNOSTICS_RUN ? new Net : nullptr), + dstNet(DNN_DIAGNOSTICS_RUN ? *utilNet : net), dispatch(buildDispatchMap()) +{ + if (dataModel != NULL && lenModel > 0) + { + CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow model from memory (" << lenModel << " bytes)"); + ReadTFNetParamsFromBinaryBufferOrDie(dataModel, lenModel, &netBin); + } + if (dataConfig != NULL && lenConfig > 0) + { + CV_LOG_DEBUG(NULL, "DNN/TF: processing TensorFlow config from memory (" << lenConfig << " bytes)"); + ReadTFNetParamsFromTextBufferOrDie(dataConfig, lenConfig, &netTxt); + } + populateNet(); +} + +void TFImporter::kernelFromTensor(const tensorflow::TensorProto &tensor, Mat &dstBlob) +{ + MatShape shape; + blobShapeFromTensor(tensor, shape); + int dims = (int)shape.size(); + + // TODO: other blob types + CV_Assert(tensor.dtype() == tensorflow::DT_FLOAT || + tensor.dtype() == tensorflow::DT_HALF); + CV_Assert(dims == 4 || dims == 5); + + int out_c, input_c, depth, height, width; + if (dims == 4) + { + // REORDER kernel HWIO to OIHW + swap(shape[0], shape[2]); // IWHO + swap(shape[1], shape[3]); // IOHW + swap(shape[0], shape[1]); // OIHW + depth = 1; height = shape[2]; width = shape[3]; + } + else + { + // REORDER kernel DHWIO to OIDHW + swap(shape[0], shape[4]); // OHWID + swap(shape[1], shape[3]); // OIWHD + swap(shape[2], shape[4]); // OIDHW + depth = shape[2]; height = shape[3]; width = shape[4]; + } + out_c = shape[0]; input_c = shape[1]; + + dstBlob.create(shape, CV_32F); + + Mat tensorContent = getTensorContent(tensor, /*no copy*/false); + int size = tensorContent.total(); + CV_Assert(size == (int)dstBlob.total()); + + float *dstData = dstBlob.ptr(); + const float *data = reinterpret_cast(tensorContent.data); + + int total = out_c * input_c * depth * height * width; + for (int i_oc = 0; i_oc < out_c; i_oc++) { + for (int i_ic = 0; i_ic < input_c; i_ic++) { + for (int i_d = 0; i_d < depth; i_d++) { + for (int i_h = 0; i_h < height; i_h++) { + for (int i_w = 0; i_w < width; i_w++) { + int dst_i = input_c * depth * height * width * i_oc + + depth * height * width * i_ic + height * width * i_d + width * i_h + i_w; + int src_i = out_c * input_c * width * height * i_d + + out_c * input_c * width * i_h + out_c * input_c * i_w + out_c * i_ic + i_oc; + CV_Assert(dst_i < total); + CV_Assert(src_i < total); + dstData[dst_i] = data[src_i]; + } + } + } + } + } +} + +void TFImporter::connect(const std::map& layers_name_id_map, Net& network, const Pin& outPin, + const int input_layer_id, const int input_blob_id) +{ + std::map::const_iterator it = layers_name_id_map.find(outPin.name); + if (it == layers_name_id_map.end()) + CV_Error(Error::StsError, "Input layer not found: " + outPin.name); + + std::vector::iterator inpNameIt = std::find(netInputsNames.begin(), netInputsNames.end(), outPin.name); + int blobIndex; + if (inpNameIt == netInputsNames.end()) + blobIndex = outPin.blobIndex; + else + blobIndex = inpNameIt - netInputsNames.begin(); + network.connect(it->second, blobIndex, input_layer_id, input_blob_id); +} + +void TFImporter::connectToAllBlobs(const std::map& layer_id, Net& network, const Pin& outPin, + const int input_layer_id, const int input_blobs_count) +{ + for (int input_blob_id = 0; input_blob_id < input_blobs_count; input_blob_id++) + connect(layer_id, network, outPin, input_layer_id, input_blob_id); +} + +const tensorflow::TensorProto& TFImporter::getConstBlob(const tensorflow::NodeDef &layer, std::map const_layers, + int input_blob_index, int* actual_inp_blob_idx) { + if (input_blob_index == -1) { + for(int i = 0; i < layer.input_size(); i++) { + Pin input = parsePin(layer.input(i)); + if (const_layers.find(input.name) != const_layers.end()) { + if (input_blob_index != -1) + CV_Error(Error::StsError, "More than one input is Const op"); + + input_blob_index = i; + } + } + } + + if (input_blob_index == -1) + CV_Error(Error::StsError, "Const input blob for weights not found"); + + Pin kernel_inp = parsePin(layer.input(input_blob_index)); + if (const_layers.find(kernel_inp.name) == const_layers.end()) + CV_Error(Error::StsError, "Input [" + layer.input(input_blob_index) + + "] for node [" + layer.name() + "] not found"); + if (kernel_inp.blobIndex != 0) + CV_Error(Error::StsError, "Unsupported kernel input"); + + if(actual_inp_blob_idx) { + *actual_inp_blob_idx = input_blob_index; + } + + int nodeIdx = const_layers.at(kernel_inp.name); + if (nodeIdx < netBin.node_size() && netBin.node(nodeIdx).name() == kernel_inp.name) + { + return netBin.node(nodeIdx).attr().at("value").tensor(); + } + else + { + CV_Assert_N(nodeIdx < netTxt.node_size(), + netTxt.node(nodeIdx).name() == kernel_inp.name); + return netTxt.node(nodeIdx).attr().at("value").tensor(); + } +} + +static void addConstNodes(tensorflow::GraphDef& net, std::map& const_layers, + std::set& layers_to_ignore) +{ + CV_LOG_DEBUG(NULL, "DNN/TF: addConstNodes(): handling " << net.node_size() << " nodes..."); + for (int li = 0; li < net.node_size(); li++) + { + const tensorflow::NodeDef &layer = net.node(li); + String name = layer.name(); + String type = layer.op(); - const tensorflow::TensorProto& betaTensor = getConstBlob(layer, value_id, 2); - if (!betaTensor.tensor_content().empty()) + //CV_LOG_DEBUG(NULL, "DNN/TF: layer_id=" << li << " - '" << name << "' @ " << type); + + try + { + if (type == "Dequantize") { - layerParams.blobs.resize(layerParams.blobs.size() + 1); - layerParams.set("has_bias", true); - blobFromTensor(betaTensor, layerParams.blobs.back()); + // Example of Dequantize node: + // name: "conv2d_1/bias" + // op: "Dequantize" + // input: "conv2d_1/bias_quantized_const" (tensor of dtype DT_QUINT8) + // input: "conv2d_1/bias_quantized_min" + // input: "conv2d_1/bias_quantized_max" + // attr { key: "T" value { type: DT_QUINT8 } } (quantized type) + // attr { key: "mode" value { s: "MIN_FIRST" } } (quantization technique) + CV_CheckEQ(layer.input_size(), 3, "Dequantize: 3 inputs is supported only"); + for (int i = 0; i < 3; ++i) + CV_Assert(const_layers.find(layer.input(i)) != const_layers.end()); + CV_Assert(hasLayerAttr(layer, "mode") && + getLayerAttr(layer, "mode").s() == "MIN_FIRST"); + + int tensorId = const_layers[layer.input(0)]; + int minId = const_layers[layer.input(1)]; + int maxId = const_layers[layer.input(2)]; + + tensorflow::TensorProto* tensor = net.mutable_node(tensorId) + ->mutable_attr()->at("value") + .mutable_tensor(); + CV_CheckEQ((int)tensor->dtype(), (int)tensorflow::DT_QUINT8, ""); + + Mat qMin = getTensorContent(net.node(minId).attr().at("value").tensor()); + Mat qMax = getTensorContent(net.node(maxId).attr().at("value").tensor()); + CV_CheckEQ(qMin.total(), (size_t)1, ""); + CV_CheckTypeEQ(qMin.type(), CV_32FC1, ""); + CV_CheckEQ(qMax.total(), (size_t)1, ""); + CV_CheckTypeEQ(qMax.type(), CV_32FC1, ""); + + Mat content = getTensorContent(*tensor); + + float minVal = qMin.at(0); + float rangeScale = (qMax.at(0) - minVal) / 255; + CV_Assert(rangeScale >= 0); + content.convertTo(content, CV_32FC1, rangeScale, + rangeScale * cvRound(minVal / rangeScale)); + + tensor->set_dtype(tensorflow::DT_FLOAT); + tensor->set_tensor_content(content.data, content.total() * content.elemSize1()); + + net.mutable_node(tensorId)->set_name(name); + CV_Assert(const_layers.insert(std::make_pair(name, tensorId)).second); + layers_to_ignore.insert(name); + continue; } - else - layerParams.set("has_bias", false); + else if (type != "Const") + continue; // only Const parameters are supported + + if (layer.attr().find("value") != layer.attr().end()) + { + CV_Assert(const_layers.insert(std::make_pair(name, li)).second); + } + layers_to_ignore.insert(name); + } + catch (const std::exception& e) + { + CV_LOG_ERROR(NULL, "DNN/TF: Can't handle node='" << name << "'. Exception: " << e.what()); + throw; + } + } + CV_LOG_DEBUG(NULL, "DNN/TF: layers_to_ignore.size() = " << layers_to_ignore.size()); +} + +// If all inputs of specific layer have the same data layout we can say that +// this layer's output has this data layout too. Returns DATA_LAYOUT_UNKNOWN otherwise. +DataLayout TFImporter::predictOutputDataLayout(const tensorflow::NodeDef& layer) +{ + DataLayout layout = getDataLayout(layer); + if (layout != DATA_LAYOUT_UNKNOWN) + { + CV_LOG_DEBUG(NULL, "DNN/TF: predictOutputDataLayout(" << layer.name() << " @ " << layer.op() << ") => " << (int)layout << " (from attrs)"); + return layout; + } - Mat mean, std; - if (isTraining) + // Determine layout by layer's inputs + for (int i = 0, n = layer.input_size(); i < n; ++i) + { + std::map::const_iterator it = data_layouts.find(getNodeName(layer.input(i))); + if (it != data_layouts.end()) + { + if (layout != DATA_LAYOUT_UNKNOWN) { - if (layerParams.blobs.size() == 2) - CV_Error(Error::StsNotImplemented, "Cannot determine number " - "of parameters for batch normalization layer."); - mean = Mat::zeros(1, layerParams.blobs[2].total(), CV_32F); - std = Mat::ones(1, layerParams.blobs[2].total(), CV_32F); - - // Add an extra layer: Mean-Variance normalization - LayerParams mvnParams; - std::string mvnName = name + "/MVN"; - CV_Assert(layer_id.find(mvnName) == layer_id.end()); - int mvnId = dstNet.addLayer(mvnName, "MVN", mvnParams); - layer_id[mvnName] = mvnId; - connect(layer_id, dstNet, inpId, mvnId, 0); - inpId = Pin(mvnName); + if (it->second != layout && it->second != DATA_LAYOUT_UNKNOWN) + return DATA_LAYOUT_UNKNOWN; } else - { - blobFromTensor(getConstBlob(layer, value_id, 3), mean); - blobFromTensor(getConstBlob(layer, value_id, 4), std); - } - layerParams.blobs[0] = mean; - layerParams.blobs[1] = std; + layout = it->second; + } + } - if (hasLayerAttr(layer, "epsilon")) - layerParams.set("eps", getLayerAttr(layer, "epsilon").f()); + if (layout != DATA_LAYOUT_UNKNOWN) + { + CV_LOG_DEBUG(NULL, "DNN/TF: predictOutputDataLayout(" << layer.name() << " @ " << layer.op() << ") => " << (int)layout << " (from inputs)"); + return layout; + } - int id = dstNet.addLayer(name, "BatchNorm", layerParams); - layer_id[name] = id; + // Determine layout by layer's consumers recursively. + std::map::const_iterator it = data_layouts.find(layer.name()); + CV_Assert(it != data_layouts.end()); + return it->second; +} - // one input only - connect(layer_id, dstNet, inpId, id, 0); - } - else if (type == "Conv2DBackpropInput") - { - // op: "Conv2DBackpropInput" - // input: "conv2d_transpose/output_shape" - // input: "weights" - // input: "input" - CV_CheckEQ(num_inputs, 3, "Expected output shape, weights and input nodes"); +Ptr dummy_constructor(LayerParams & params) +{ + return new Layer(params); +} - layerParams.set("bias_term", false); - layerParams.blobs.resize(1); +void TFImporter::populateNet() +{ + CV_Assert(netBin.ByteSize() || netTxt.ByteSize()); - StrIntVector next_layers = getNextLayers(net, name, "BiasAdd"); - if (next_layers.size() == 1) - { - layerParams.set("bias_term", true); - layerParams.blobs.resize(2); + CV_LOG_INFO(NULL, "DNN/TF: parsing model" + << (netBin.has_versions() ? cv::format(" produced by TF v%d (min_consumer=%d)", (int)netBin.versions().producer(), (int)netBin.versions().min_consumer()) : cv::String(" (N/A version info)")) + << ". Number of nodes = " << netBin.node_size() + ); - int weights_layer_index = next_layers[0].second; + if (netTxt.ByteSize()) + { + CV_LOG_INFO(NULL, "DNN/TF: parsing config" + << (netTxt.has_versions() ? cv::format(" produced by TF v%d (min_consumer=%d)", (int)netTxt.versions().producer(), (int)netTxt.versions().min_consumer()) : cv::String(" (N/A version info)")) + << ". Number of nodes = " << netTxt.node_size() + ); - blobFromTensor(getConstBlob(net.node(weights_layer_index), value_id), layerParams.blobs[1]); - ExcludeLayer(net, weights_layer_index, 0, false); - layers_to_ignore.insert(next_layers[0].first); - } + RemoveIdentityOps(netBin); + CV_LOG_DEBUG(NULL, "DNN/TF: RemoveIdentityOps(model) => " << netBin.node_size() << " nodes"); + RemoveIdentityOps(netTxt); + CV_LOG_DEBUG(NULL, "DNN/TF: RemoveIdentityOps(config) => " << netTxt.node_size() << " nodes"); - kernelFromTensor(getConstBlob(layer, value_id, 1), layerParams.blobs[0]); - - const int* kshape = layerParams.blobs[0].size.p; - const int kernelH = kshape[2]; - const int kernelW = kshape[3]; - layerParams.set("kernel_h", kernelH); - layerParams.set("kernel_w", kernelW); - layerParams.set("num_output", kshape[1]); - - setStrides(layerParams, layer); - setPadding(layerParams, layer); - - // For convolution layer, output shape computes as - // o = 1 + (i - k + 2*p) / s - // i - input size, o - output size, k - kernel size, p - pad, s - stride - // In TensorFlow, p == 0 is padMode == 'VALID' or p == (k - 1) / 2 - // considering that k is odd. - // SAME: o = 1 + (i - 1) / s - // VALID: o = 1 + i / s - // Deconvolution's layer output shape computes as - // SAME: o = 1 + (i - 1)*s - // VALID: o = (i - 1)*s - // If output_shape differs from formulas above then adjust padding is applied. - - const int strideY = layerParams.get("stride_h"); - const int strideX = layerParams.get("stride_w"); - Mat outShape = getTensorContent(getConstBlob(layer, value_id, 0)); - const int outH = outShape.at(1); - const int outW = outShape.at(2); - if (layerParams.get("pad_mode") == "SAME") - { - layerParams.set("adj_w", (outW - 1) % strideX); - layerParams.set("adj_h", (outH - 1) % strideY); - } - else if (layerParams.get("pad_mode") == "VALID") - { - layerParams.set("adj_w", (outW - kernelW) % strideX); - layerParams.set("adj_h", (outH - kernelH) % strideY); - } - int id = dstNet.addLayer(name, "Deconvolution", layerParams); - layer_id[name] = id; + sortByExecutionOrder(netTxt); + CV_LOG_DEBUG(NULL, "DNN/TF: sortByExecutionOrder(config) => " << netTxt.node_size() << " nodes"); + } + else + { + removePhaseSwitches(netBin); + CV_LOG_DEBUG(NULL, "DNN/TF: removePhaseSwitches(model) => " << netBin.node_size() << " nodes"); - // one input only - connect(layer_id, dstNet, parsePin(layer.input(2)), id, 0); - } - else if (type == "BlockLSTM") - { - // op: "BlockLSTM" - // input: "lstm_block_wrapper/ToInt64/x" (ignore, number of time stamps) - // input: "input" - // input: "lstm_block_wrapper/zeros" (ignore) - // input: "lstm_block_wrapper/zeros" (ignore) - // input: "lstm_block_wrapper/kernel" - // input: "lstm_block_wrapper/w_i_diag" - // input: "lstm_block_wrapper/w_f_diag" - // input: "lstm_block_wrapper/w_o_diag" - // input: "lstm_block_wrapper/bias" - CV_CheckEQ(num_inputs, 9, "Unexpected number of input nodes"); - - if (hasLayerAttr(layer, "forget_bias")) - layerParams.set("forget_bias", getLayerAttr(layer, "forget_bias").f()); - - if (hasLayerAttr(layer, "forget_bias")) - { - float cellClip = getLayerAttr(layer, "cell_clip").f(); - // Cell clip disabled if it's negative. - if (cellClip >= 0) - { - layerParams.set("use_cell_clip", true); - layerParams.set("cell_clip", cellClip); - } - } + RemoveIdentityOps(netBin); + CV_LOG_DEBUG(NULL, "DNN/TF: RemoveIdentityOps(model) => " << netBin.node_size() << " nodes"); - Mat W, Wh, Wx, b; - blobFromTensor(getConstBlob(layer, value_id, 4), W); - blobFromTensor(getConstBlob(layer, value_id, 8), b); - const int outSize = W.cols / 4; + simplifySubgraphs(netBin); + CV_LOG_DEBUG(NULL, "DNN/TF: simplifySubgraphs(model) => " << netBin.node_size() << " nodes"); + sortByExecutionOrder(netBin); + CV_LOG_DEBUG(NULL, "DNN/TF: sortByExecutionOrder(model) => " << netBin.node_size() << " nodes"); + } - // IGFO->IFOG - float* weightData = (float*)W.data; - for (int i = 0; i < W.rows; ++i) - for (int j = 0; j < outSize; ++j) - { - std::swap(weightData[i * W.cols + 1 * outSize + j], - weightData[i * W.cols + 2 * outSize + j]); - std::swap(weightData[i * W.cols + 2 * outSize + j], - weightData[i * W.cols + 3 * outSize + j]); - } - Wx = W.rowRange(0, W.rows - outSize).t(); - Wh = W.rowRange(W.rows - outSize, W.rows).t(); + tensorflow::GraphDef& net = netTxt.ByteSize() != 0 ? netTxt : netBin; - layerParams.blobs.resize(3); - layerParams.blobs[0] = Wh; - layerParams.blobs[1] = Wx; - layerParams.blobs[2] = b; + int layersSize = net.node_size(); - if (hasLayerAttr(layer, "use_peephole")) - { - bool usePeephole = getLayerAttr(layer, "use_peephole").b(); - if (usePeephole) - { - layerParams.set("use_peephole", true); - layerParams.blobs.resize(6); - for (int i = 0; i < 3; ++i) - { - Mat w; - blobFromTensor(getConstBlob(layer, value_id, 5 + i), w); - w = w.reshape(1, w.total()); // Single column. - w = Mat::diag(w); // Make a diagonal matrix. - layerParams.blobs[3 + i] = w; - } - } - } + // Pre-fill data layouts where they are set explicitly. + // Assuming that nodes are in topological order + for (int i = layersSize - 1; i >= 0; --i) + { + const tensorflow::NodeDef& layer = net.node(i); + std::string name = layer.name(); - int id = dstNet.addLayer(name, "LSTM", layerParams); - layer_id[name] = id; + CV_LOG_DEBUG(NULL, "DNN/TF: node(" << i << " - '" << name << "') propagating layout..."); - // one input only - connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); - data_layouts[name] = DATA_LAYOUT_UNKNOWN; - } - else if (type == "ResizeNearestNeighbor" || type == "ResizeBilinear" || type == "FusedResizeAndPadConv2D") + try { - CV_CheckGT(num_inputs, 0, ""); - std::string convWeights = ""; - if (type == "FusedResizeAndPadConv2D") + DataLayout layout = getDataLayout(layer); + std::map::iterator it = data_layouts.find(name); + if (it != data_layouts.end()) { - // input: "mul_1" - // input: "decoder/ResizeBilinear/size" - // input: "decoder/decoder_conv0/Conv2D_dummy_paddings" - // input: "decoder/decoder_conv0/weights" - CV_CheckEQ(num_inputs, 4, "Number of input for FusedResizeAndPadConv2D"); - - Mat paddings = getTensorContent(getConstBlob(layer, value_id, 2)); - CV_CheckEQ(countNonZero(paddings), 0, "Unsupported mode"); - - convWeights = layer.input(3); - layer.mutable_input()->DeleteSubrange(2, 2); // FIXIT do NOT modify input model - num_inputs = layer.input_size(); - name = name + "/resize"; - - if (hasLayerAttr(layer, "resize_align_corners")) + if (layout != DATA_LAYOUT_UNKNOWN) { - // FIXIT do NOT modify input model - layer.mutable_attr()->insert( - ::google::protobuf::MapPair("align_corners", - getLayerAttr(layer, "resize_align_corners"))); + if (it->second == DATA_LAYOUT_UNKNOWN) + it->second = layout; + else if (it->second != layout) + { + it->second = DATA_LAYOUT_UNKNOWN; + layout = DATA_LAYOUT_UNKNOWN; + } } - } - if (num_inputs == 2) - { - Mat outSize = getTensorContent(getConstBlob(layer, value_id, 1)); - CV_CheckTypeEQ(outSize.type(), CV_32SC1, ""); CV_CheckEQ(outSize.total(), (size_t)2, ""); - layerParams.set("height", outSize.at(0, 0)); - layerParams.set("width", outSize.at(0, 1)); - } - else if (num_inputs == 3) - { - Mat factorHeight = getTensorContent(getConstBlob(layer, value_id, 1)); - Mat factorWidth = getTensorContent(getConstBlob(layer, value_id, 2)); - factorHeight.convertTo(factorHeight, CV_32F); - factorWidth.convertTo(factorWidth, CV_32F); - layerParams.set("zoom_factor_x", factorWidth.at(0)); - layerParams.set("zoom_factor_y", factorHeight.at(0)); + else + layout = it->second; } else - CV_Check(num_inputs, num_inputs == 2 || num_inputs == 3, ""); - - if (type == "ResizeNearestNeighbor") - layerParams.set("interpolation", "nearest"); - else - layerParams.set("interpolation", "bilinear"); - - if (hasLayerAttr(layer, "align_corners")) - layerParams.set("align_corners", getLayerAttr(layer, "align_corners").b()); - - if (hasLayerAttr(layer, "half_pixel_centers")) - layerParams.set("half_pixel_centers", getLayerAttr(layer, "half_pixel_centers").b()); - - int id = dstNet.addLayer(name, "Resize", layerParams); - layer_id[name] = id; - - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - - // Step back to add convolution - if (type == "FusedResizeAndPadConv2D") - { - tensorflow::NodeDef conv = layer_; - conv.clear_input(); - conv.add_input(name); - conv.add_input(convWeights); - conv.set_op("Conv2D"); - parseNode(conv); - } - } - else if (type == "L2Normalize") - { - // op: "L2Normalize" - // input: "input" - // input: "reduction_indices" (axis) - CV_CheckEQ(num_inputs, 2, ""); - Mat reductionIndices = getTensorContent(getConstBlob(layer, value_id, 1)); - CV_Assert(reductionIndices.type() == CV_32SC1); - - const int numAxes = reductionIndices.total(); - if (getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) - for (int i = 0; i < numAxes; ++i) - reductionIndices.at(i) = toNCHW(reductionIndices.at(i)); - - cv::sort(reductionIndices, reductionIndices, SORT_ASCENDING); - for (int i = 1; i < numAxes; ++i) - { - CV_Assert(reductionIndices.at(i) == reductionIndices.at(i - 1) + 1); - // Axes have the same sign. - CV_Assert(reductionIndices.at(i) * reductionIndices.at(i - 1) >= 0); - } - layerParams.set("start_axis", reductionIndices.at(0)); - layerParams.set("end_axis", reductionIndices.at(numAxes - 1)); + data_layouts[name] = layout; - int id = dstNet.addLayer(name, "Normalize", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - } - else if (type == "PriorBox") - { - CV_CheckEQ(num_inputs, 2, ""); - if (hasLayerAttr(layer, "min_size")) - layerParams.set("min_size", getLayerAttr(layer, "min_size").i()); - if (hasLayerAttr(layer, "max_size")) - layerParams.set("max_size", getLayerAttr(layer, "max_size").i()); - if (hasLayerAttr(layer, "flip")) - layerParams.set("flip", getLayerAttr(layer, "flip").b()); - if (hasLayerAttr(layer, "clip")) - layerParams.set("clip", getLayerAttr(layer, "clip").b()); - if (hasLayerAttr(layer, "offset")) - layerParams.set("offset", getLayerAttr(layer, "offset").f()); - if (hasLayerAttr(layer, "step")) - layerParams.set("step", getLayerAttr(layer, "step").f()); - - const std::string paramNames[] = {"variance", "aspect_ratio", "scales", - "width", "height"}; - for (int i = 0; i < 5; ++i) + // Specify input layers to have the same data layout. + for (int j = 0; j < layer.input_size(); ++j) { - if (hasLayerAttr(layer, paramNames[i])) + name = getNodeName(layer.input(j)); + it = data_layouts.find(name); + if (it != data_layouts.end()) { - Mat values = getTensorContent(getLayerAttr(layer, paramNames[i]).tensor()); - layerParams.set(paramNames[i], - DictValue::arrayReal((float*)values.data, values.total())); + if (layout != DATA_LAYOUT_UNKNOWN) + { + if (it->second == DATA_LAYOUT_UNKNOWN) + it->second = layout; + else if (it->second != layout) + it->second = DATA_LAYOUT_UNKNOWN; + } } + else + data_layouts[name] = layout; } - int id = dstNet.addLayer(name, "PriorBox", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1); - data_layouts[name] = DATA_LAYOUT_UNKNOWN; } - else if (type == "Softmax") + catch (const std::exception& e) { - CV_CheckGT(num_inputs, 0, ""); - if (hasLayerAttr(layer, "axis")) - layerParams.set("axis", getLayerAttr(layer, "axis").i()); - - int id = dstNet.addLayer(name, "Softmax", layerParams); - layer_id[name] = id; - connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); + CV_LOG_ERROR(NULL, "DNN/TF: Can't propagate layout for node='" << name << "'. Exception: " << e.what()); + throw; } - else if (type == "CropAndResize") - { - // op: "CropAndResize" - // input: "input" - // input: "boxes" - // input: "sizes" - CV_CheckEQ(num_inputs, 3, ""); + } - Mat cropSize = getTensorContent(getConstBlob(layer, value_id, 2)); - CV_CheckTypeEQ(cropSize.type(), CV_32SC1, ""); CV_CheckEQ(cropSize.total(), (size_t)2, ""); + addConstNodes(netBin, value_id, layers_to_ignore); + addConstNodes(netTxt, value_id, layers_to_ignore); - layerParams.set("height", cropSize.at(0)); - layerParams.set("width", cropSize.at(1)); - int id = dstNet.addLayer(name, "CropAndResize", layerParams); - layer_id[name] = id; + for (int li = 0; li < layersSize; li++) + { + const tensorflow::NodeDef& layer = net.node(li); - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - connect(layer_id, dstNet, parsePin(layer.input(1)), id, 1); - } - else if (type == "Mean" || type == "Sum") - { - // Computes the mean of elements across dimensions of a tensor. - // If keepdims is false (default) reduces input_tensor along the dimensions given in axis, - // else the reduced dimensions are retained with length 1. - // if indices = [1, 2] in NHWC layout we use global pooling: NxCxHxW --Pooling--> NxCx1x1 - // if keepdims is false we use Flatten after Pooling: out_shape = NxC - // if indices = [0] we use a global pooling by indices. - // To return correct shape, we use Reshape after Pooling. To determine input shape use Slice for input, - // if keepdims is false we use Flatten after Slice. - // Example: input_shape = NxCxHxW - // determine out shape: NxCxHxW --Slice--> 1xCxHxW - // out_shape = 1xCxHxW if keepDims else (1xCxHxW --Flatten--> CxHxW) - // global pool: NxCxHxW --Flatten--> Nx(C*H*W) --Reshape--> 1x1xNx(C*H*W) --Pooling--> 1x1x1x(C*H*W) --Reshape--> out_shape - CV_CheckGT(num_inputs, 0, ""); - - Mat indices = getTensorContent(getConstBlob(layer, value_id, 1)); - CV_Assert(indices.type() == CV_32SC1); - - // There are two attributes, "keepdims" and a deprecated "keep_dims". - bool keepDims = false; - if (hasLayerAttr(layer, "keepdims")) - keepDims = getLayerAttr(layer, "keepdims").b(); - else if (hasLayerAttr(layer, "keep_dims")) - keepDims = getLayerAttr(layer, "keep_dims").b(); - - if (indices.total() == 1 && indices.at(0) == 0) - { - LayerParams flattenLp; - std::string flattenName = name + "/flatten"; - CV_Assert(layer_id.find(flattenName) == layer_id.end()); - int flattenId = dstNet.addLayer(flattenName, "Flatten", flattenLp); - layer_id[flattenName] = flattenId; - connect(layer_id, dstNet, parsePin(layer.input(0)), flattenId, 0); - - LayerParams reshapeLp; - std::string reshapeName = name + "/reshape"; - CV_Assert(layer_id.find(reshapeName) == layer_id.end()); - reshapeLp.set("axis", 0); - reshapeLp.set("num_axes", 1); - int newShape[] = {1, 1, -1}; - reshapeLp.set("dim", DictValue::arrayInt(&newShape[0], 3)); - - int reshapeId = dstNet.addLayer(reshapeName, "Reshape", reshapeLp); - layer_id[reshapeName] = reshapeId; - connect(layer_id, dstNet, Pin(flattenName), reshapeId, 0); - - LayerParams avgLp; - std::string avgName = name + "/avg"; - CV_Assert(layer_id.find(avgName) == layer_id.end()); - avgLp.set("pool", type == "Mean" ? "ave" : "sum"); - // pooling kernel H x 1 - avgLp.set("global_pooling_h", true); - avgLp.set("kernel_w", 1); - int avgId = dstNet.addLayer(avgName, "Pooling", avgLp); - layer_id[avgName] = avgId; - connect(layer_id, dstNet, Pin(reshapeName), avgId, 0); - - LayerParams sliceLp; - std::string layerShapeName = name + "/slice"; - CV_Assert(layer_id.find(layerShapeName) == layer_id.end()); - sliceLp.set("axis", 0); - int begin[] = {0}; - int size[] = {1}; - sliceLp.set("begin", DictValue::arrayInt(&begin[0], 1)); - sliceLp.set("size", DictValue::arrayInt(&size[0], 1)); - int sliceId = dstNet.addLayer(layerShapeName, "Slice", sliceLp); - layer_id[layerShapeName] = sliceId; - connect(layer_id, dstNet, Pin(layer.input(0)), sliceId, 0); - - if (!keepDims) - { - LayerParams squeezeLp; - std::string squeezeName = name + "/squeeze"; - CV_Assert(layer_id.find(squeezeName) == layer_id.end()); - squeezeLp.set("axis", 0); - squeezeLp.set("end_axis", 1); - int squeezeId = dstNet.addLayer(squeezeName, "Flatten", squeezeLp); - layer_id[squeezeName] = squeezeId; - connect(layer_id, dstNet, Pin(layerShapeName), squeezeId, 0); - layerShapeName = squeezeName; - } + const std::string name = layer.name(); + const std::string type = layer.op(); + const int ninputs = layer.input_size(); + CV_LOG_DEBUG(NULL, "DNN/TF: (" << li << "/" << layersSize << ") Parse layer " << name << " @ " << type << " with " << ninputs << " inputs"); - int id = dstNet.addLayer(name, "Reshape", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, Pin(avgName), id, 0); - connect(layer_id, dstNet, Pin(layerShapeName), id, 1); - } else if (indices.total() == 1) { - int axis = toNCHW(indices.at(0)); - if (axis == 2 || axis == 3) - { - layerParams.set("pool", type == "Mean" ? "ave" : "sum"); - layerParams.set(axis == 2 ? "kernel_w" : "kernel_h", 1); - layerParams.set(axis == 2 ? "global_pooling_h" : "global_pooling_w", true); - int id = dstNet.addLayer(name, "Pooling", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); - - if (!keepDims) - { - // To keep correct order after squeeze dims we first need to change layout from NCHW to NHWC - LayerParams permLP; - int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. - std::string permName = name + "/nchw"; - Pin inpId = Pin(name); - addPermuteLayer(order, permName, inpId); - - LayerParams squeezeLp; - std::string squeezeName = name + "/squeeze"; - CV_Assert(layer_id.find(squeezeName) == layer_id.end()); - squeezeLp.set("axis", indices.at(0)); - squeezeLp.set("end_axis", indices.at(0) + 1); - int squeezeId = dstNet.addLayer(squeezeName, "Flatten", squeezeLp); - layer_id[squeezeName] = squeezeId; - connect(layer_id, dstNet, Pin(permName), squeezeId, 0); - } - } - else if (axis == 1) - { - int order[] = {0, 2, 3, 1}; // From OpenCV's NCHW to NHWC. - Pin inpId = parsePin(layer.input(0)); - addPermuteLayer(order, name + "/nhwc", inpId); - - layerParams.set("pool", type == "Mean" ? "ave" : "sum"); - layerParams.set("kernel_h", 1); - layerParams.set("global_pooling_w", true); - int id = dstNet.addLayer(name, "Pooling", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, inpId, id, 0); - - if (!keepDims) - { - LayerParams squeezeLp; - std::string squeezeName = name + "/squeeze"; - CV_Assert(layer_id.find(squeezeName) == layer_id.end()); - int channel_id = 3; // TF NHWC layout - squeezeLp.set("axis", channel_id - 1); - squeezeLp.set("end_axis", channel_id); - int squeezeId = dstNet.addLayer(squeezeName, "Flatten", squeezeLp); - layer_id[squeezeName] = squeezeId; - connect(layer_id, dstNet, Pin(name), squeezeId, 0); - } - else - { - int order[] = {0, 3, 1, 2}; // From NHWC to OpenCV's NCHW. - Pin inpId = parsePin(name); - addPermuteLayer(order, name + "/nchw", inpId); - } - } - } else { - if (indices.total() != 2 || indices.at(0) != 1 || indices.at(1) != 2) - CV_Error(Error::StsNotImplemented, "Unsupported mode of reduce_mean or reduce_sum operation."); + parseNode(layer); + } - layerParams.set("pool", type == "Mean" ? "ave" : "sum"); - layerParams.set("global_pooling", true); - int id = dstNet.addLayer(name, "Pooling", layerParams); - layer_id[name] = id; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + for (size_t i = 0; i < netInputsNames.size(); i++) + { + CV_LOG_DEBUG(NULL, "DNN/TF: Model input: " << i << " - '" << netInputsNames[i] << "'"); + CV_Assert(!netInputsNames[i].empty()); + } + dstNet.setInputsNames(netInputsNames); + CV_LOG_DEBUG(NULL, "DNN/TF: ===================== Import completed ====================="); +} - if (!keepDims) - { - LayerParams flattenLp; - std::string flattenName = name + "/flatten"; - CV_Assert(layer_id.find(flattenName) == layer_id.end()); - int flattenId = dstNet.addLayer(flattenName, "Flatten", flattenLp); - layer_id[flattenName] = flattenId; - connect(layer_id, dstNet, Pin(name), flattenId, 0); - } - } - } - else if (type == "Pack") - { - // op: tf.stack(list of tensors, axis=0) - // Join a list of inputs along a new axis. - // The "axis" specifies the index of the new axis in the dimensions of the output. - // Example: given a list with "N" tensors of shape (C, H, W): - // if axis == 0 then the output tensor will have the shape (N, C, H, W), - // if axis == 1 then the output tensor will have the shape (C, N, H, W). - CV_CheckGT(num_inputs, 0, ""); - CV_Assert(hasLayerAttr(layer, "axis")); - int dim = (int)getLayerAttr(layer, "axis").i(); - if (dim != 0) - CV_Error(Error::StsNotImplemented, "Unsupported mode of pack operation."); - - CV_Assert(hasLayerAttr(layer, "N")); - int num = (int)getLayerAttr(layer, "N").i(); - CV_CheckEQ(num_inputs, num, ""); - std::string base_name = name + "/reshape_"; - std::vector reshape_ids; - for (int i = 0; i < num; i++) { - std::ostringstream ss; - ss << i; - std::string reshape_name = base_name + ss.str(); - LayerParams reshapeLP; - reshapeLP.set("axis", dim); - reshapeLP.set("num_axes", 1); - int outShape[] = {1, -1}; - reshapeLP.set("dim", DictValue::arrayInt(&outShape[0], 2)); - int id = dstNet.addLayer(reshape_name, "Reshape", reshapeLP); - layer_id[reshape_name] = id; - reshape_ids.push_back(id); - connect(layer_id, dstNet, parsePin(layer.input(i)), id, 0); - } +void TFImporter::addPermuteLayer(const int* order, const std::string& permName, Pin& inpId) +{ + LayerParams permLP; + permLP.set("order", DictValue::arrayInt(order, 4)); + CV_Assert(layer_id.find(permName) == layer_id.end()); + int permId = dstNet.addLayer(permName, "Permute", permLP); + layer_id[permName] = permId; + connect(layer_id, dstNet, inpId, permId, 0); + inpId = Pin(permName); +} - layerParams.set("axis", dim); - int id = dstNet.addLayer(name, "Concat", layerParams); - layer_id[name] = id; +void TFImporter::parseNode(const tensorflow::NodeDef& layer) +{ + tensorflow::GraphDef& net = netTxt.ByteSize() != 0 ? netTxt : netBin; - for (int li = 0; li < num; li++) - dstNet.connect(reshape_ids[li], 0, id, li); - } - else if (type == "ClipByValue") - { - // op: "ClipByValue" - // input: "input" - // input: "mix" - // input: "max" - CV_CheckEQ(num_inputs, 3, ""); + const std::string& name = layer.name(); + const std::string& type = layer.op(); - Mat minValue = getTensorContent(getConstBlob(layer, value_id, 1)); - Mat maxValue = getTensorContent(getConstBlob(layer, value_id, 2)); - CV_CheckEQ(minValue.total(), (size_t)1, ""); CV_CheckTypeEQ(minValue.type(), CV_32FC1, ""); - CV_CheckEQ(maxValue.total(), (size_t)1, ""); CV_CheckTypeEQ(maxValue.type(), CV_32FC1, ""); + LayerParams layerParams; + try + { - layerParams.set("min_value", minValue.at(0)); - layerParams.set("max_value", maxValue.at(0)); + if (layers_to_ignore.find(name) != layers_to_ignore.end()) + { + CV_LOG_DEBUG(NULL, "DNN/TF: ignored"); + return; + } - int id = dstNet.addLayer(name, "ReLU6", layerParams); - layer_id[name] = id; + DataLayout predictedLayout = predictOutputDataLayout(layer); + data_layouts[name] = predictedLayout; - connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + DispatchMap::const_iterator iter = dispatch.find(type); + if (iter != dispatch.end()) + { + ((*this).*(iter->second))(net, layer, layerParams); } - else if (type == "LeakyRelu") + else { - CV_CheckGT(num_inputs, 0, ""); - CV_Assert(hasLayerAttr(layer, "alpha")); - layerParams.set("negative_slope", getLayerAttr(layer, "alpha").f()); + if (DNN_DIAGNOSTICS_RUN && !LayerFactory::createLayerInstance(type, layerParams)) + { + CV_LOG_ERROR(NULL, "DNN/TF: Node='" << name << "' of type='"<< type + << "' is not supported. This error won't be displayed again."); + LayerFactory::registerLayer(type, dummy_constructor); + } - int id = dstNet.addLayer(name, "ReLU", layerParams); - layer_id[name] = id; - connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); + parseCustomLayer(net, layer, layerParams); } - else if (type == "Abs" || type == "Tanh" || type == "Sigmoid" || - type == "Relu" || type == "Elu" || type == "Exp" || - type == "Identity" || type == "Relu6") + } + catch (const std::exception& e) + { + if (!DNN_DIAGNOSTICS_RUN) { - CV_CheckGT(num_inputs, 0, ""); - std::string dnnType = type; - if (type == "Abs") dnnType = "AbsVal"; - else if (type == "Tanh") dnnType = "TanH"; - else if (type == "Relu") dnnType = "ReLU"; - else if (type == "Relu6") dnnType = "ReLU6"; - else if (type == "Elu") dnnType = "ELU"; - - int id = dstNet.addLayer(name, dnnType, layerParams); - layer_id[name] = id; - connectToAllBlobs(layer_id, dstNet, parsePin(layer.input(0)), id, num_inputs); + CV_LOG_ERROR(NULL, "DNN/TF: Can't parse layer for node='" << name << "' of type='" << type + << "'. Exception: " << e.what()); + throw; } else { - // Importer does not know how to map this TensorFlow's operation onto OpenCV's layer. - // However we create a layer with the same type and rely that user defined a custom layer. - - // All the attributes are added to LayerParams. - google::protobuf::Map attr = layer.attr(); - for (google::protobuf::Map::const_iterator ai = attr.begin(); - ai != attr.end(); ++ai) - { - if (ai->second.value_case() == tensorflow::AttrValue::kS) // string - layerParams.set(ai->first, ai->second.s()); - if (ai->second.value_case() == tensorflow::AttrValue::kI) // int64 - layerParams.set(ai->first, ai->second.i()); - if (ai->second.value_case() == tensorflow::AttrValue::kF) // float - layerParams.set(ai->first, ai->second.f()); - if (ai->second.value_case() == tensorflow::AttrValue::kB) // bool - layerParams.set(ai->first, ai->second.b()); - } - - // All the Const input nodes are added to layer's blobs. - std::vector inputsNames; - for (int i = 0; i < num_inputs; ++i) - { - // Check if input is a Const node. - if (value_id.find(layer.input(i)) != value_id.end()) - { - Mat blob = getTensorContent(getConstBlob(layer, value_id, i)); - layerParams.blobs.push_back(blob); - } - else - inputsNames.push_back(layer.input(i)); - } - int id = dstNet.addLayer(name, type, layerParams); - layer_id[name] = id; + CV_LOG_ERROR(NULL, "DNN/TF: Can't parse layer for node='" << name << "' of type='" << type + << "'. Exception: " << e.what()); - for (int i = 0; i < inputsNames.size(); ++i) + // internal layer failure (didnt call addLayer) + if (dstNet.getLayerId(name) == -1) { - connect(layer_id, dstNet, parsePin(inputsNames[i]), id, i); + int id = dstNet.addLayer(name, type, layerParams); + layer_id[name] = id; } } } - catch (const std::exception& e) - { - CV_LOG_ERROR(NULL, "DNN/TF: Can't parse layer for node='" << name << "'. Exception: " << e.what()); - throw; - } } } // namespace diff --git a/modules/dnn/test/test_backends.cpp b/modules/dnn/test/test_backends.cpp index aab4c6f50774..e8c7e700f651 100644 --- a/modules/dnn/test/test_backends.cpp +++ b/modules/dnn/test/test_backends.cpp @@ -204,7 +204,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe) Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false); float scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 1.5e-2 : 0.0; float iouDiff = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0; - float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.252 : FLT_MIN; + float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.262 : FLT_MIN; processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt", inp, "detection_out", "", scoreDiff, iouDiff, detectionConfThresh); expectNoFallbacksFromIE(net); @@ -359,8 +359,8 @@ TEST_P(DNNTestNetwork, OpenPose_pose_coco) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION); #endif - const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0056 : 0.0; - const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.072 : 0.0; + const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.009 : 0.0; + const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0; processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt", Size(46, 46), "", "", l1, lInf); expectNoFallbacksFromIE(net); @@ -380,8 +380,8 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi) #endif // output range: [-0.001, 0.97] - const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0; - const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.16 : 0.0; + const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.02 : 0.0; + const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.2 : 0.0; processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt", Size(46, 46), "", "", l1, lInf); expectNoFallbacksFromIE(net); diff --git a/modules/dnn/test/test_ie_models.cpp b/modules/dnn/test/test_ie_models.cpp index b285e91d9654..760651c5c0b5 100644 --- a/modules/dnn/test/test_ie_models.cpp +++ b/modules/dnn/test/test_ie_models.cpp @@ -307,6 +307,15 @@ TEST_P(DNNTestOpenVINO, models) ASSERT_FALSE(backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) << "Inference Engine backend is required"; +#if INF_ENGINE_VER_MAJOR_EQ(2021040000) + if (targetId == DNN_TARGET_MYRIAD && ( + modelName == "person-detection-retail-0013" || // ncDeviceOpen:1013 Failed to find booted device after boot + modelName == "age-gender-recognition-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot + ) + ) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION); +#endif + #if INF_ENGINE_VER_MAJOR_GE(2020020000) if (targetId == DNN_TARGET_MYRIAD && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) { diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index 81ea1dcdd0e7..b8f45a204cb3 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -349,6 +349,7 @@ TEST_P(Test_ONNX_layers, Concatenation) if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); } testONNXModels("concatenation"); + testONNXModels("concat_const_blobs"); } TEST_P(Test_ONNX_layers, Eltwise3D) @@ -485,8 +486,6 @@ TEST_P(Test_ONNX_layers, MatMul) { if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER); - if (backend == DNN_BACKEND_CUDA) - applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); // not supported testONNXModels("matmul_2d"); testONNXModels("matmul_3d"); @@ -735,8 +734,6 @@ TEST_P(Test_ONNX_layers, MatmulWithTwoInputs) #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2020040000) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE); #endif - if (backend == DNN_BACKEND_CUDA) - applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); testONNXModels("matmul_with_two_inputs"); } diff --git a/modules/dnn/test/test_torch_importer.cpp b/modules/dnn/test/test_torch_importer.cpp index f1d636895baa..48725f244e57 100644 --- a/modules/dnn/test/test_torch_importer.cpp +++ b/modules/dnn/test/test_torch_importer.cpp @@ -290,9 +290,14 @@ TEST_P(Test_Torch_layers, net_padding) TEST_P(Test_Torch_layers, net_non_spatial) { -#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000) +#if defined(INF_ENGINE_RELEASE) && ( \ + INF_ENGINE_VER_MAJOR_EQ(2021030000) || \ + INF_ENGINE_VER_MAJOR_EQ(2021040000) \ +) if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD) - applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // crash + // 2021.3: crash + // 2021.4: [ GENERAL_ERROR ] AssertionFailed: !out.networkInputs.empty() + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16) diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 16016082a2eb..e51bd9204491 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -1337,6 +1337,13 @@ CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector& key const std::vector& matchesMask=std::vector(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); /** @overload */ +CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector& keypoints1, + InputArray img2, const std::vector& keypoints2, + const std::vector& matches1to2, InputOutputArray outImg, + const int matchesThickness, const Scalar& matchColor=Scalar::all(-1), + const Scalar& singlePointColor=Scalar::all(-1), const std::vector& matchesMask=std::vector(), + DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); + CV_EXPORTS_AS(drawMatchesKnn) void drawMatches( InputArray img1, const std::vector& keypoints1, InputArray img2, const std::vector& keypoints2, const std::vector >& matches1to2, InputOutputArray outImg, diff --git a/modules/features2d/src/draw.cpp b/modules/features2d/src/draw.cpp index 84fb0aca39ab..86f06dc8858d 100644 --- a/modules/features2d/src/draw.cpp +++ b/modules/features2d/src/draw.cpp @@ -183,7 +183,8 @@ static void _prepareImgAndDrawKeypoints( InputArray img1, const std::vector& keypoints1, @@ -207,6 +208,21 @@ void drawMatches( InputArray img1, const std::vector& keypoints1, const std::vector& matches1to2, InputOutputArray outImg, const Scalar& matchColor, const Scalar& singlePointColor, const std::vector& matchesMask, DrawMatchesFlags flags ) +{ + drawMatches( img1, keypoints1, + img2, keypoints2, + matches1to2, outImg, + 1, matchColor, + singlePointColor, matchesMask, + flags); +} + +void drawMatches( InputArray img1, const std::vector& keypoints1, + InputArray img2, const std::vector& keypoints2, + const std::vector& matches1to2, InputOutputArray outImg, + const int matchesThickness, const Scalar& matchColor, + const Scalar& singlePointColor, const std::vector& matchesMask, + DrawMatchesFlags flags ) { if( !matchesMask.empty() && matchesMask.size() != matches1to2.size() ) CV_Error( Error::StsBadSize, "matchesMask must have the same size as matches1to2" ); @@ -226,11 +242,12 @@ void drawMatches( InputArray img1, const std::vector& keypoints1, CV_Assert(i2 >= 0 && i2 < static_cast(keypoints2.size())); const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2]; - _drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags ); + _drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, matchesThickness ); } } } + void drawMatches( InputArray img1, const std::vector& keypoints1, InputArray img2, const std::vector& keypoints2, const std::vector >& matches1to2, InputOutputArray outImg, @@ -254,7 +271,7 @@ void drawMatches( InputArray img1, const std::vector& keypoints1, if( matchesMask.empty() || matchesMask[i][j] ) { const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2]; - _drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags ); + _drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, 1 ); } } } diff --git a/modules/features2d/src/sift.simd.hpp b/modules/features2d/src/sift.simd.hpp index b5033459b957..60129b1535b5 100644 --- a/modules/features2d/src/sift.simd.hpp +++ b/modules/features2d/src/sift.simd.hpp @@ -450,31 +450,184 @@ class findScaleSpaceExtremaT const sift_wt* currptr = img.ptr(r); const sift_wt* prevptr = prev.ptr(r); const sift_wt* nextptr = next.ptr(r); + int c = SIFT_IMG_BORDER; - for( int c = SIFT_IMG_BORDER; c < cols-SIFT_IMG_BORDER; c++) +#if CV_SIMD && !(DoG_TYPE_SHORT) + const int vecsize = v_float32::nlanes; + for( ; c <= cols-SIFT_IMG_BORDER - vecsize; c += vecsize) + { + v_float32 val = vx_load(&currptr[c]); + v_float32 _00,_01,_02; + v_float32 _10, _12; + v_float32 _20,_21,_22; + + v_float32 vmin,vmax; + + + v_float32 cond = v_abs(val) > vx_setall_f32((float)threshold); + if (!v_check_any(cond)) + { + continue; + } + + _00 = vx_load(&currptr[c-step-1]); _01 = vx_load(&currptr[c-step]); _02 = vx_load(&currptr[c-step+1]); + _10 = vx_load(&currptr[c -1]); _12 = vx_load(&currptr[c +1]); + _20 = vx_load(&currptr[c+step-1]); _21 = vx_load(&currptr[c+step]); _22 = vx_load(&currptr[c+step+1]); + + vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22))); + vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22))); + + v_float32 condp = cond & (val > vx_setall_f32(0)) & (val >= vmax); + v_float32 condm = cond & (val < vx_setall_f32(0)) & (val <= vmin); + + cond = condp | condm; + if (!v_check_any(cond)) + { + continue; + } + + _00 = vx_load(&prevptr[c-step-1]); _01 = vx_load(&prevptr[c-step]); _02 = vx_load(&prevptr[c-step+1]); + _10 = vx_load(&prevptr[c -1]); _12 = vx_load(&prevptr[c +1]); + _20 = vx_load(&prevptr[c+step-1]); _21 = vx_load(&prevptr[c+step]); _22 = vx_load(&prevptr[c+step+1]); + + vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22))); + vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22))); + + condp &= (val >= vmax); + condm &= (val <= vmin); + + cond = condp | condm; + if (!v_check_any(cond)) + { + continue; + } + + v_float32 _11p = vx_load(&prevptr[c]); + v_float32 _11n = vx_load(&nextptr[c]); + + v_float32 max_middle = v_max(_11n,_11p); + v_float32 min_middle = v_min(_11n,_11p); + + _00 = vx_load(&nextptr[c-step-1]); _01 = vx_load(&nextptr[c-step]); _02 = vx_load(&nextptr[c-step+1]); + _10 = vx_load(&nextptr[c -1]); _12 = vx_load(&nextptr[c +1]); + _20 = vx_load(&nextptr[c+step-1]); _21 = vx_load(&nextptr[c+step]); _22 = vx_load(&nextptr[c+step+1]); + + vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22))); + vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22))); + + condp &= (val >= v_max(vmax,max_middle)); + condm &= (val <= v_min(vmin,min_middle)); + + cond = condp | condm; + if (!v_check_any(cond)) + { + continue; + } + + int mask = v_signmask(cond); + for (int k = 0; k 0 ? j - 1 : n - 1; + int r2 = j < n-1 ? j + 1 : 0; + + if( hist[j] > hist[l] && hist[j] > hist[r2] && hist[j] >= mag_thr ) + { + float bin = j + 0.5f * (hist[l]-hist[r2]) / (hist[l] - 2*hist[j] + hist[r2]); + bin = bin < 0 ? n + bin : bin >= n ? bin - n : bin; + kpt.angle = 360.f - (float)((360.f/n) * bin); + if(std::abs(kpt.angle - 360.f) < FLT_EPSILON) + kpt.angle = 0.f; + + kpts_.push_back(kpt); + } + } + } + } + +#endif //CV_SIMD && !(DoG_TYPE_SHORT) + + // vector loop reminder, better predictibility and less branch density + for( ; c < cols-SIFT_IMG_BORDER; c++) { sift_wt val = currptr[c]; + if (std::abs(val) <= threshold) + continue; + + sift_wt _00,_01,_02; + sift_wt _10, _12; + sift_wt _20,_21,_22; + _00 = currptr[c-step-1]; _01 = currptr[c-step]; _02 = currptr[c-step+1]; + _10 = currptr[c -1]; _12 = currptr[c +1]; + _20 = currptr[c+step-1]; _21 = currptr[c+step]; _22 = currptr[c+step+1]; + + bool calculate = false; + if (val > 0) + { + sift_wt vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22))); + if (val >= vmax) + { + _00 = prevptr[c-step-1]; _01 = prevptr[c-step]; _02 = prevptr[c-step+1]; + _10 = prevptr[c -1]; _12 = prevptr[c +1]; + _20 = prevptr[c+step-1]; _21 = prevptr[c+step]; _22 = prevptr[c+step+1]; + vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22))); + if (val >= vmax) + { + _00 = nextptr[c-step-1]; _01 = nextptr[c-step]; _02 = nextptr[c-step+1]; + _10 = nextptr[c -1]; _12 = nextptr[c +1]; + _20 = nextptr[c+step-1]; _21 = nextptr[c+step]; _22 = nextptr[c+step+1]; + vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22))); + if (val >= vmax) + { + sift_wt _11p = prevptr[c], _11n = nextptr[c]; + calculate = (val >= std::max(_11p,_11n)); + } + } + } + + } else { // val cant be zero here (first abs took care of zero), must be negative + sift_wt vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22))); + if (val <= vmin) + { + _00 = prevptr[c-step-1]; _01 = prevptr[c-step]; _02 = prevptr[c-step+1]; + _10 = prevptr[c -1]; _12 = prevptr[c +1]; + _20 = prevptr[c+step-1]; _21 = prevptr[c+step]; _22 = prevptr[c+step+1]; + vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22))); + if (val <= vmin) + { + _00 = nextptr[c-step-1]; _01 = nextptr[c-step]; _02 = nextptr[c-step+1]; + _10 = nextptr[c -1]; _12 = nextptr[c +1]; + _20 = nextptr[c+step-1]; _21 = nextptr[c+step]; _22 = nextptr[c+step+1]; + vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22))); + if (val <= vmin) + { + sift_wt _11p = prevptr[c], _11n = nextptr[c]; + calculate = (val <= std::min(_11p,_11n)); + } + } + } + } - // find local extrema with pixel accuracy - if( std::abs(val) > threshold && - ((val > 0 && val >= currptr[c-1] && val >= currptr[c+1] && - val >= currptr[c-step-1] && val >= currptr[c-step] && val >= currptr[c-step+1] && - val >= currptr[c+step-1] && val >= currptr[c+step] && val >= currptr[c+step+1] && - val >= nextptr[c] && val >= nextptr[c-1] && val >= nextptr[c+1] && - val >= nextptr[c-step-1] && val >= nextptr[c-step] && val >= nextptr[c-step+1] && - val >= nextptr[c+step-1] && val >= nextptr[c+step] && val >= nextptr[c+step+1] && - val >= prevptr[c] && val >= prevptr[c-1] && val >= prevptr[c+1] && - val >= prevptr[c-step-1] && val >= prevptr[c-step] && val >= prevptr[c-step+1] && - val >= prevptr[c+step-1] && val >= prevptr[c+step] && val >= prevptr[c+step+1]) || - (val < 0 && val <= currptr[c-1] && val <= currptr[c+1] && - val <= currptr[c-step-1] && val <= currptr[c-step] && val <= currptr[c-step+1] && - val <= currptr[c+step-1] && val <= currptr[c+step] && val <= currptr[c+step+1] && - val <= nextptr[c] && val <= nextptr[c-1] && val <= nextptr[c+1] && - val <= nextptr[c-step-1] && val <= nextptr[c-step] && val <= nextptr[c-step+1] && - val <= nextptr[c+step-1] && val <= nextptr[c+step] && val <= nextptr[c+step+1] && - val <= prevptr[c] && val <= prevptr[c-1] && val <= prevptr[c+1] && - val <= prevptr[c-step-1] && val <= prevptr[c-step] && val <= prevptr[c-step+1] && - val <= prevptr[c+step-1] && val <= prevptr[c+step] && val <= prevptr[c+step+1]))) + if (calculate) { CV_TRACE_REGION("pixel_candidate"); diff --git a/modules/gapi/include/opencv2/gapi.hpp b/modules/gapi/include/opencv2/gapi.hpp index e4b20214796a..f10dfd471dbf 100644 --- a/modules/gapi/include/opencv2/gapi.hpp +++ b/modules/gapi/include/opencv2/gapi.hpp @@ -2,7 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // -// Copyright (C) 2018 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation #ifndef OPENCV_GAPI_HPP @@ -19,6 +19,7 @@ @} @defgroup gapi_std_backends G-API Standard Backends @defgroup gapi_compile_args G-API Graph Compilation Arguments + @defgroup gapi_serialization G-API Serialization functionality @} */ diff --git a/modules/gapi/include/opencv2/gapi/core.hpp b/modules/gapi/include/opencv2/gapi/core.hpp index 597315136ff7..b7f65b6719c3 100644 --- a/modules/gapi/include/opencv2/gapi/core.hpp +++ b/modules/gapi/include/opencv2/gapi/core.hpp @@ -29,6 +29,10 @@ */ namespace cv { namespace gapi { +/** + * @brief This namespace contains G-API Operation Types for OpenCV + * Core module functionality. + */ namespace core { using GMat2 = std::tuple; using GMat3 = std::tuple; // FIXME: how to avoid this? @@ -575,6 +579,12 @@ namespace core { return std::make_tuple(empty_gopaque_desc(), empty_array_desc(), empty_array_desc()); } }; + + G_TYPED_KERNEL(GTranspose, , "org.opencv.core.transpose") { + static GMatDesc outMeta(GMatDesc in) { + return in.withSize({in.size.height, in.size.width}); + } + }; } // namespace core namespace streaming { @@ -1927,6 +1937,21 @@ GAPI_EXPORTS std::tuple,GArray,GArray> kmeans(const GArray& data, const int K, const GArray& bestLabels, const TermCriteria& criteria, const int attempts, const KmeansFlags flags); + +/** @brief Transposes a matrix. + +The function transposes the matrix: +\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f] + +@note + - Function textual ID is "org.opencv.core.transpose" + - No complex conjugation is done in case of a complex matrix. It should be done separately if needed. + +@param src input array. +*/ +GAPI_EXPORTS GMat transpose(const GMat& src); + + namespace streaming { /** @brief Gets dimensions from Mat. diff --git a/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp b/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp index 5539e244bab5..009c19688bf9 100644 --- a/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp +++ b/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp @@ -40,6 +40,10 @@ namespace gimpl namespace gapi { +/** + * @brief This namespace contains G-API CPU backend functions, + * structures, and symbols. + */ namespace cpu { /** @@ -492,7 +496,7 @@ class GCPUStKernelImpl: public cv::detail::KernelTag #define GAPI_OCV_KERNEL_ST(Name, API, State) \ struct Name: public cv::GCPUStKernelImpl \ - +/// @private class gapi::cpu::GOCVFunctor : public gapi::GFunctor { public: diff --git a/modules/gapi/include/opencv2/gapi/cpu/stereo.hpp b/modules/gapi/include/opencv2/gapi/cpu/stereo.hpp index f7d79e9b3c12..e2a2242bd0b8 100644 --- a/modules/gapi/include/opencv2/gapi/cpu/stereo.hpp +++ b/modules/gapi/include/opencv2/gapi/cpu/stereo.hpp @@ -25,8 +25,8 @@ struct GAPI_EXPORTS StereoInitParam { int numDisparities = 0; int blockSize = 21; - double baseline = 70.; - double focus = 1000.; + double baseline = 63.5; + double focus = 3.6; }; } // namespace cpu diff --git a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp index dbb36d801ded..53b68c4e2188 100644 --- a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp @@ -25,6 +25,9 @@ namespace cv { namespace gapi { +/** + * @brief This namespace contains G-API Fluid backend functions, structures, and symbols. + */ namespace fluid { /** diff --git a/modules/gapi/include/opencv2/gapi/garg.hpp b/modules/gapi/include/opencv2/gapi/garg.hpp index 20f2233bf9c3..ee6ee81e1cc6 100644 --- a/modules/gapi/include/opencv2/gapi/garg.hpp +++ b/modules/gapi/include/opencv2/gapi/garg.hpp @@ -2,7 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // -// Copyright (C) 2018-2020 Intel Corporation +// Copyright (C) 2018-2021 Intel Corporation #ifndef OPENCV_GAPI_GARG_HPP @@ -171,7 +171,7 @@ using GRunArgs = std::vector; * It's an ordinary overload of addition assignment operator. * * Example of usage: - * @snippet dynamic_graph.cpp GRunArgs usage + * @snippet modules/gapi/samples/dynamic_graph.cpp GRunArgs usage * */ inline GRunArgs& operator += (GRunArgs &lhs, const GRunArgs &rhs) @@ -223,7 +223,7 @@ using GRunArgsP = std::vector; * It's an ordinary overload of addition assignment operator. * * Example of usage: - * @snippet dynamic_graph.cpp GRunArgsP usage + * @snippet modules/gapi/samples/dynamic_graph.cpp GRunArgsP usage * */ inline GRunArgsP& operator += (GRunArgsP &lhs, const GRunArgsP &rhs) @@ -235,8 +235,39 @@ inline GRunArgsP& operator += (GRunArgsP &lhs, const GRunArgsP &rhs) namespace gapi { - GAPI_EXPORTS cv::GRunArgsP bind(cv::GRunArgs &results); - GAPI_EXPORTS cv::GRunArg bind(cv::GRunArgP &out); // FIXME: think more about it +/** + * \addtogroup gapi_serialization + * @{ + * + * @brief G-API functions and classes for serialization and deserialization. + */ +/** @brief Wraps deserialized output GRunArgs to GRunArgsP which can be used by GCompiled. + * + * Since it's impossible to get modifiable output arguments from deserialization + * it needs to be wrapped by this function. + * + * Example of usage: + * @snippet modules/gapi/samples/api_ref_snippets.cpp bind after deserialization + * + * @param out_args deserialized GRunArgs. + * @return the same GRunArgs wrapped in GRunArgsP. + * @see deserialize + */ +GAPI_EXPORTS cv::GRunArgsP bind(cv::GRunArgs &out_args); +/** @brief Wraps output GRunArgsP available during graph execution to GRunArgs which can be serialized. + * + * GRunArgsP is pointer-to-value, so to be serialized they need to be binded to real values + * which this function does. + * + * Example of usage: + * @snippet modules/gapi/samples/api_ref_snippets.cpp bind before serialization + * + * @param out output GRunArgsP available during graph execution. + * @return the same GRunArgsP wrapped in serializable GRunArgs. + * @see serialize + */ +GAPI_EXPORTS cv::GRunArg bind(cv::GRunArgP &out); // FIXME: think more about it +/** @} */ } template inline GRunArgs gin(const Ts&... args) diff --git a/modules/gapi/include/opencv2/gapi/garray.hpp b/modules/gapi/include/opencv2/gapi/garray.hpp index 32799bc07e15..d7b365f7f983 100644 --- a/modules/gapi/include/opencv2/gapi/garray.hpp +++ b/modules/gapi/include/opencv2/gapi/garray.hpp @@ -340,21 +340,79 @@ namespace detail /** \addtogroup gapi_data_objects * @{ */ - +/** + * @brief `cv::GArray` template class represents a list of objects + * of class `T` in the graph. + * + * `cv::GArray` describes a functional relationship between + * operations consuming and producing arrays of objects of class + * `T`. The primary purpose of `cv::GArray` is to represent a + * dynamic list of objects -- where the size of the list is not known + * at the graph construction or compile time. Examples include: corner + * and feature detectors (`cv::GArray`), object detection + * and tracking results (`cv::GArray`). Programmers can use + * their own types with `cv::GArray` in the custom operations. + * + * Similar to `cv::GScalar`, `cv::GArray` may be value-initialized + * -- in this case a graph-constant value is associated with the object. + * + * `GArray` is a virtual counterpart of `std::vector`, which is + * usually used to represent the `GArray` data in G-API during the + * execution. + * + * @sa `cv::GOpaque` + */ template class GArray { public: // Host type (or Flat type) - the type this GArray is actually // specified to. + /// @private using HT = typename detail::flatten_g::type>::type; + /** + * @brief Constructs a value-initialized `cv::GArray` + * + * `cv::GArray` objects may have their values + * be associated at graph construction time. It is useful when + * some operation has a `cv::GArray` input which doesn't change during + * the program execution, and is set only once. In this case, + * there is no need to declare such `cv::GArray` as a graph input. + * + * @note The value of `cv::GArray` may be overwritten by assigning some + * other `cv::GArray` to the object using `operator=` -- on the + * assigment, the old association or value is discarded. + * + * @param v a std::vector to associate with this + * `cv::GArray` object. Vector data is copied into the + * `cv::GArray` (no reference to the passed data is held). + */ explicit GArray(const std::vector& v) // Constant value constructor : m_ref(detail::GArrayU(detail::VectorRef(v))) { putDetails(); } + + /** + * @overload + * @brief Constructs a value-initialized `cv::GArray` + * + * @param v a std::vector to associate with this + * `cv::GArray` object. Vector data is moved into the `cv::GArray`. + */ explicit GArray(std::vector&& v) // Move-constructor : m_ref(detail::GArrayU(detail::VectorRef(std::move(v)))) { putDetails(); } - GArray() { putDetails(); } // Empty constructor - explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor - : m_ref(ref) { putDetails(); } // (used by GCall, not for users) + + /** + * @brief Constructs an empty `cv::GArray` + * + * Normally, empty G-API data objects denote a starting point of + * the graph. When an empty `cv::GArray` is assigned to a result + * of some operation, it obtains a functional link to this + * operation (and is not empty anymore). + */ + GArray() { putDetails(); } // Empty constructor + + /// @private + explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor + : m_ref(ref) { putDetails(); } // (used by GCall, not for users) /// @private detail::GArrayU strip() const { diff --git a/modules/gapi/include/opencv2/gapi/gasync_context.hpp b/modules/gapi/include/opencv2/gapi/gasync_context.hpp index 69ce530fc93b..f49b59822d9d 100644 --- a/modules/gapi/include/opencv2/gapi/gasync_context.hpp +++ b/modules/gapi/include/opencv2/gapi/gasync_context.hpp @@ -17,6 +17,13 @@ namespace cv { namespace gapi{ + +/** + * @brief This namespace contains experimental G-API functionality, + * functions or structures in this namespace are subjects to change or + * removal in the future releases. This namespace also contains + * functions which API is not stabilized yet. + */ namespace wip { /** diff --git a/modules/gapi/include/opencv2/gapi/gcommon.hpp b/modules/gapi/include/opencv2/gapi/gcommon.hpp index 8119e397ebf4..d3c280816ff9 100644 --- a/modules/gapi/include/opencv2/gapi/gcommon.hpp +++ b/modules/gapi/include/opencv2/gapi/gcommon.hpp @@ -44,6 +44,7 @@ namespace detail CV_UNKNOWN, // Unknown, generic, opaque-to-GAPI data type unsupported in graph seriallization CV_BOOL, // bool user G-API data CV_INT, // int user G-API data + CV_INT64, // int64_t user G-API data CV_DOUBLE, // double user G-API data CV_FLOAT, // float user G-API data CV_UINT64, // uint64_t user G-API data @@ -61,6 +62,7 @@ namespace detail template struct GOpaqueTraits; template struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_UNKNOWN; }; template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT; }; + template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT64; }; template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_DOUBLE; }; template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_FLOAT; }; template<> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_UINT64; }; @@ -195,6 +197,14 @@ struct GCompileArg using GCompileArgs = std::vector; +inline cv::GCompileArgs& operator += ( cv::GCompileArgs &lhs, + const cv::GCompileArgs &rhs) +{ + lhs.reserve(lhs.size() + rhs.size()); + lhs.insert(lhs.end(), rhs.begin(), rhs.end()); + return lhs; +} + /** * @brief Wraps a list of arguments (a parameter pack) into a vector of * compilation arguments (cv::GCompileArg). diff --git a/modules/gapi/include/opencv2/gapi/gframe.hpp b/modules/gapi/include/opencv2/gapi/gframe.hpp index 13fd5d6d2957..96913dc4cc57 100644 --- a/modules/gapi/include/opencv2/gapi/gframe.hpp +++ b/modules/gapi/include/opencv2/gapi/gframe.hpp @@ -28,14 +28,54 @@ struct GOrigin; /** \addtogroup gapi_data_objects * @{ */ +/** + * @brief GFrame class represents an image or media frame in the graph. + * + * GFrame doesn't store any data itself, instead it describes a + * functional relationship between operations consuming and producing + * GFrame objects. + * + * GFrame is introduced to handle various media formats (e.g., NV12 or + * I420) under the same type. Various image formats may differ in the + * number of planes (e.g. two for NV12, three for I420) and the pixel + * layout inside. GFrame type allows to handle these media formats in + * the graph uniformly -- the graph structure will not change if the + * media format changes, e.g. a different camera or decoder is used + * with the same graph. G-API provides a number of operations which + * operate directly on GFrame, like `infer<>()` or + * renderFrame(); these operations are expected to handle different + * media formats inside. There is also a number of accessor + * operations like BGR(), Y(), UV() -- these operations provide + * access to frame's data in the familiar cv::GMat form, which can be + * used with the majority of the existing G-API operations. These + * accessor functions may perform color space converion on the fly if + * the image format of the GFrame they are applied to differs from the + * operation's semantic (e.g. the BGR() accessor is called on an NV12 + * image frame). + * + * GFrame is a virtual counterpart of cv::MediaFrame. + * + * @sa cv::MediaFrame, cv::GFrameDesc, BGR(), Y(), UV(), infer<>(). + */ class GAPI_EXPORTS_W_SIMPLE GFrame { public: - GAPI_WRAP GFrame(); // Empty constructor - GFrame(const GNode &n, std::size_t out); // Operation result constructor - - GOrigin& priv(); // Internal use only - const GOrigin& priv() const; // Internal use only + /** + * @brief Constructs an empty GFrame + * + * Normally, empty G-API data objects denote a starting point of + * the graph. When an empty GFrame is assigned to a result of some + * operation, it obtains a functional link to this operation (and + * is not empty anymore). + */ + GAPI_WRAP GFrame(); // Empty constructor + + /// @private + GFrame(const GNode &n, std::size_t out); // Operation result constructor + /// @private + GOrigin& priv(); // Internal use only + /// @private + const GOrigin& priv() const; // Internal use only private: std::shared_ptr m_priv; diff --git a/modules/gapi/include/opencv2/gapi/gkernel.hpp b/modules/gapi/include/opencv2/gapi/gkernel.hpp index f70e50253d0c..cfac552bfee0 100644 --- a/modules/gapi/include/opencv2/gapi/gkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/gkernel.hpp @@ -372,6 +372,7 @@ namespace gapi { // Prework: model "Device" API before it gets to G-API headers. // FIXME: Don't mix with internal Backends class! + /// @private class GAPI_EXPORTS GBackend { public: @@ -412,6 +413,7 @@ namespace std namespace cv { namespace gapi { + /// @private class GFunctor { public: diff --git a/modules/gapi/include/opencv2/gapi/gmat.hpp b/modules/gapi/include/opencv2/gapi/gmat.hpp index 11c3071f03e7..7bea97bbc52b 100644 --- a/modules/gapi/include/opencv2/gapi/gmat.hpp +++ b/modules/gapi/include/opencv2/gapi/gmat.hpp @@ -30,29 +30,57 @@ struct GOrigin; * @brief G-API data objects used to build G-API expressions. * * These objects do not own any particular data (except compile-time - * associated values like with cv::GScalar) and are used to construct - * graphs. + * associated values like with cv::GScalar or `cv::GArray`) and are + * used only to construct graphs. * * Every graph in G-API starts and ends with data objects. * * Once constructed and compiled, G-API operates with regular host-side * data instead. Refer to the below table to find the mapping between - * G-API and regular data types. + * G-API and regular data types when passing input and output data + * structures to G-API: * * G-API data type | I/O data type * ------------------ | ------------- - * cv::GMat | cv::Mat + * cv::GMat | cv::Mat, cv::UMat, cv::RMat * cv::GScalar | cv::Scalar * `cv::GArray` | std::vector * `cv::GOpaque` | T + * cv::GFrame | cv::MediaFrame + */ +/** + * @brief GMat class represents image or tensor data in the + * graph. + * + * GMat doesn't store any data itself, instead it describes a + * functional relationship between operations consuming and producing + * GMat objects. + * + * GMat is a virtual counterpart of Mat and UMat, but it + * doesn't mean G-API use Mat or UMat objects internally to represent + * GMat objects -- the internal data representation may be + * backend-specific or optimized out at all. + * + * @sa Mat, GMatDesc */ class GAPI_EXPORTS_W_SIMPLE GMat { public: + /** + * @brief Constructs an empty GMat + * + * Normally, empty G-API data objects denote a starting point of + * the graph. When an empty GMat is assigned to a result of some + * operation, it obtains a functional link to this operation (and + * is not empty anymore). + */ GAPI_WRAP GMat(); // Empty constructor - GMat(const GNode &n, std::size_t out); // Operation result constructor + /// @private + GMat(const GNode &n, std::size_t out); // Operation result constructor + /// @private GOrigin& priv(); // Internal use only + /// @private const GOrigin& priv() const; // Internal use only private: diff --git a/modules/gapi/include/opencv2/gapi/gopaque.hpp b/modules/gapi/include/opencv2/gapi/gopaque.hpp index 00f07184223a..979a9db8c4b5 100644 --- a/modules/gapi/include/opencv2/gapi/gopaque.hpp +++ b/modules/gapi/include/opencv2/gapi/gopaque.hpp @@ -307,15 +307,40 @@ namespace detail /** \addtogroup gapi_data_objects * @{ */ - +/** + * @brief `cv::GOpaque` template class represents an object of + * class `T` in the graph. + * + * `cv::GOpaque` describes a functional relationship between operations + * consuming and producing object of class `T`. `cv::GOpaque` is + * designed to extend G-API with user-defined data types, which are + * often required with user-defined operations. G-API can't apply any + * optimizations to user-defined types since these types are opaque to + * the framework. However, there is a number of G-API operations + * declared with `cv::GOpaque` as a return type, + * e.g. cv::gapi::streaming::timestamp() or cv::gapi::streaming::size(). + * + * @sa `cv::GArray` + */ template class GOpaque { public: // Host type (or Flat type) - the type this GOpaque is actually // specified to. + /// @private using HT = typename detail::flatten_g>::type; + /** + * @brief Constructs an empty `cv::GOpaque` + * + * Normally, empty G-API data objects denote a starting point of + * the graph. When an empty `cv::GOpaque` is assigned to a result + * of some operation, it obtains a functional link to this + * operation (and is not empty anymore). + */ GOpaque() { putDetails(); } // Empty constructor + + /// @private explicit GOpaque(detail::GOpaqueU &&ref) // GOpaqueU-based constructor : m_ref(ref) { putDetails(); } // (used by GCall, not for users) diff --git a/modules/gapi/include/opencv2/gapi/gproto.hpp b/modules/gapi/include/opencv2/gapi/gproto.hpp index fbcccb38ea71..6271e470b076 100644 --- a/modules/gapi/include/opencv2/gapi/gproto.hpp +++ b/modules/gapi/include/opencv2/gapi/gproto.hpp @@ -71,7 +71,7 @@ struct GIOProtoArgs * It's an ordinary overload of addition assignment operator. * * Example of usage: - * @snippet dynamic_graph.cpp GIOProtoArgs usage + * @snippet modules/gapi/samples/dynamic_graph.cpp GIOProtoArgs usage * */ template diff --git a/modules/gapi/include/opencv2/gapi/gscalar.hpp b/modules/gapi/include/opencv2/gapi/gscalar.hpp index d4af2cab5d60..c6edc33b75cc 100644 --- a/modules/gapi/include/opencv2/gapi/gscalar.hpp +++ b/modules/gapi/include/opencv2/gapi/gscalar.hpp @@ -25,18 +25,83 @@ struct GOrigin; /** \addtogroup gapi_data_objects * @{ */ - +/** + * @brief GScalar class represents cv::Scalar data in the graph. + * + * GScalar may be associated with a cv::Scalar value, which becomes + * its constant value bound in graph compile time. cv::GScalar describes a + * functional relationship between operations consuming and producing + * GScalar objects. + * + * GScalar is a virtual counterpart of cv::Scalar, which is usually used + * to represent the GScalar data in G-API during the execution. + * + * @sa Scalar + */ class GAPI_EXPORTS_W_SIMPLE GScalar { public: - GAPI_WRAP GScalar(); // Empty constructor - explicit GScalar(const cv::Scalar& s); // Constant value constructor from cv::Scalar + /** + * @brief Constructs an empty GScalar + * + * Normally, empty G-API data objects denote a starting point of + * the graph. When an empty GScalar is assigned to a result of some + * operation, it obtains a functional link to this operation (and + * is not empty anymore). + */ + GAPI_WRAP GScalar(); + + /** + * @brief Constructs a value-initialized GScalar + * + * In contrast with GMat (which can be either an explicit graph input + * or a result of some operation), GScalars may have their values + * be associated at graph construction time. It is useful when + * some operation has a GScalar input which doesn't change during + * the program execution, and is set only once. In this case, + * there is no need to declare such GScalar as a graph input. + * + * @note The value of GScalar may be overwritten by assigning some + * other GScalar to the object using `operator=` -- on the + * assigment, the old GScalar value is discarded. + * + * @param s a cv::Scalar value to associate with this GScalar object. + */ + explicit GScalar(const cv::Scalar& s); + + /** + * @overload + * @brief Constructs a value-initialized GScalar + * + * @param s a cv::Scalar value to associate with this GScalar object. + */ explicit GScalar(cv::Scalar&& s); // Constant value move-constructor from cv::Scalar + /** + * @overload + * @brief Constructs a value-initialized GScalar + * + * @param v0 A `double` value to associate with this GScalar. Note + * that only the first component of a four-component cv::Scalar is + * set to this value, with others remain zeros. + * + * This constructor overload is not marked `explicit` and can be + * used in G-API expression code like this: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp gscalar_implicit + * + * Here operator+(GMat,GScalar) is used to wrap cv::gapi::addC() + * and a value-initialized GScalar is created on the fly. + * + * @overload + */ GScalar(double v0); // Constant value constructor from double - GScalar(const GNode &n, std::size_t out); // Operation result constructor + /// @private + GScalar(const GNode &n, std::size_t out); // Operation result constructor + /// @private GOrigin& priv(); // Internal use only + /// @private const GOrigin& priv() const; // Internal use only private: diff --git a/modules/gapi/include/opencv2/gapi/gstreaming.hpp b/modules/gapi/include/opencv2/gapi/gstreaming.hpp index 4e579caafbaa..50abe69f87b7 100644 --- a/modules/gapi/include/opencv2/gapi/gstreaming.hpp +++ b/modules/gapi/include/opencv2/gapi/gstreaming.hpp @@ -71,6 +71,15 @@ using GOptRunArgP = util::variant< >; using GOptRunArgsP = std::vector; +using GOptRunArg = util::variant< + optional, + optional, + optional, + optional, + optional +>; +using GOptRunArgs = std::vector; + namespace detail { template inline GOptRunArgP wrap_opt_arg(optional& arg) { @@ -196,7 +205,7 @@ class GAPI_EXPORTS_W_SIMPLE GStreamingCompiled * @param s a shared pointer to IStreamSource representing the * input video stream. */ - GAPI_WRAP void setSource(const gapi::wip::IStreamSource::Ptr& s); + void setSource(const gapi::wip::IStreamSource::Ptr& s); /** * @brief Constructs and specifies an input video stream for a @@ -255,7 +264,7 @@ class GAPI_EXPORTS_W_SIMPLE GStreamingCompiled // NB: Used from python /// @private -- Exclude this function from OpenCV documentation - GAPI_WRAP std::tuple pull(); + GAPI_WRAP std::tuple> pull(); /** * @brief Get some next available data from the pipeline. @@ -371,6 +380,39 @@ class GAPI_EXPORTS_W_SIMPLE GStreamingCompiled }; /** @} */ +namespace gapi { + +/** + * @brief This namespace contains G-API functions, structures, and + * symbols related to the Streaming execution mode. + * + * Some of the operations defined in this namespace (e.g. size(), + * BGR(), etc.) can be used in the traditional execution mode too. + */ +namespace streaming { +/** + * @brief Specify queue capacity for streaming execution. + * + * In the streaming mode the pipeline steps are connected with queues + * and this compile argument controls every queue's size. + */ +struct GAPI_EXPORTS queue_capacity +{ + explicit queue_capacity(size_t cap = 1) : capacity(cap) { }; + size_t capacity; +}; +/** @} */ +} // namespace streaming +} // namespace gapi + +namespace detail +{ +template<> struct CompileArgTag +{ + static const char* tag() { return "gapi.queue_capacity"; } +}; +} + } #endif // OPENCV_GAPI_GSTREAMING_COMPILED_HPP diff --git a/modules/gapi/include/opencv2/gapi/imgproc.hpp b/modules/gapi/include/opencv2/gapi/imgproc.hpp index 2dbe626ff144..5c4c6f7031e6 100644 --- a/modules/gapi/include/opencv2/gapi/imgproc.hpp +++ b/modules/gapi/include/opencv2/gapi/imgproc.hpp @@ -47,6 +47,10 @@ void validateFindingContoursMeta(const int depth, const int chan, const int mode namespace cv { namespace gapi { +/** + * @brief This namespace contains G-API Operation Types for OpenCV + * ImgProc module functionality. + */ namespace imgproc { using GMat2 = std::tuple; using GMat3 = std::tuple; // FIXME: how to avoid this? diff --git a/modules/gapi/include/opencv2/gapi/infer.hpp b/modules/gapi/include/opencv2/gapi/infer.hpp index 6e71f59df9bf..807c82d31f89 100644 --- a/modules/gapi/include/opencv2/gapi/infer.hpp +++ b/modules/gapi/include/opencv2/gapi/infer.hpp @@ -136,11 +136,12 @@ class GInferInputsTyped } template - void setInput(const std::string& name, U in) + GInferInputsTyped& setInput(const std::string& name, U in) { m_priv->blobs.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(in)); + return *this; } using StorageT = cv::util::variant; @@ -531,7 +532,11 @@ typename Net::Result infer(Args&&... args) { } /** - * @brief Special network type + * @brief Generic network type: input and output layers are configured dynamically at runtime + * + * Unlike the network types defined with G_API_NET macro, this one + * doesn't fix number of network inputs and outputs at the compilation stage + * thus providing user with an opportunity to program them in runtime. */ struct Generic { }; @@ -649,7 +654,8 @@ namespace gapi { // A type-erased form of network parameters. // Similar to how a type-erased GKernel is represented and used. -struct GAPI_EXPORTS GNetParam { +/// @private +struct GAPI_EXPORTS_W_SIMPLE GNetParam { std::string tag; // FIXME: const? GBackend backend; // Specifies the execution model util::any params; // Backend-interpreted parameter structure @@ -660,12 +666,13 @@ struct GAPI_EXPORTS GNetParam { */ /** * @brief A container class for network configurations. Similar to - * GKernelPackage.Use cv::gapi::networks() to construct this object. + * GKernelPackage. Use cv::gapi::networks() to construct this object. * * @sa cv::gapi::networks */ struct GAPI_EXPORTS_W_SIMPLE GNetPackage { GAPI_WRAP GNetPackage() = default; + GAPI_WRAP explicit GNetPackage(std::vector nets); explicit GNetPackage(std::initializer_list ii); std::vector backends() const; std::vector networks; @@ -693,6 +700,14 @@ template cv::gapi::GNetPackage networks(Args&&... args) { return cv::gapi::GNetPackage({ cv::detail::strip(args)... }); } + +inline cv::gapi::GNetPackage& operator += ( cv::gapi::GNetPackage& lhs, + const cv::gapi::GNetPackage& rhs) { + lhs.networks.reserve(lhs.networks.size() + rhs.networks.size()); + lhs.networks.insert(lhs.networks.end(), rhs.networks.begin(), rhs.networks.end()); + return lhs; +} + } // namespace gapi } // namespace cv diff --git a/modules/gapi/include/opencv2/gapi/infer/ie.hpp b/modules/gapi/include/opencv2/gapi/infer/ie.hpp index 2bed13abc33b..2be739e51840 100644 --- a/modules/gapi/include/opencv2/gapi/infer/ie.hpp +++ b/modules/gapi/include/opencv2/gapi/infer/ie.hpp @@ -2,7 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // -// Copyright (C) 2019 Intel Corporation +// Copyright (C) 2019-2021 Intel Corporation #ifndef OPENCV_GAPI_INFER_IE_HPP #define OPENCV_GAPI_INFER_IE_HPP @@ -24,12 +24,17 @@ namespace cv { namespace gapi { // FIXME: introduce a new sub-namespace for NN? + +/** + * @brief This namespace contains G-API OpenVINO backend functions, + * structures, and symbols. + */ namespace ie { GAPI_EXPORTS cv::gapi::GBackend backend(); /** - * Specify how G-API and IE should trait input data + * Specifies how G-API and IE should trait input data * * In OpenCV, the same cv::Mat is used to represent both * image and tensor data. Sometimes those are hardly distinguishable, @@ -47,34 +52,34 @@ enum class TraitAs: int using IEConfig = std::map; namespace detail { - struct ParamDesc { - std::string model_path; - std::string weights_path; - std::string device_id; +struct ParamDesc { + std::string model_path; + std::string weights_path; + std::string device_id; - // NB: Here order follows the `Net` API - std::vector input_names; - std::vector output_names; + std::vector input_names; + std::vector output_names; - using ConstInput = std::pair; - std::unordered_map const_inputs; + using ConstInput = std::pair; + std::unordered_map const_inputs; - // NB: nun_* may differ from topology's real input/output port numbers - // (e.g. topology's partial execution) - std::size_t num_in; // How many inputs are defined in the operation - std::size_t num_out; // How many outputs are defined in the operation + std::size_t num_in; + std::size_t num_out; - enum class Kind { Load, Import }; - Kind kind; - bool is_generic; - IEConfig config; + enum class Kind {Load, Import}; + Kind kind; + bool is_generic; + IEConfig config; - std::map> reshape_table; - std::unordered_set layer_names_to_reshape; + std::map> reshape_table; + std::unordered_set layer_names_to_reshape; - // NB: Number of asyncrhonious infer requests - size_t nireq; - }; + // NB: Number of asyncrhonious infer requests + size_t nireq; + + // NB: An optional config to setup RemoteContext for IE + cv::util::any context_config; +}; } // namespace detail // FIXME: this is probably a shared (reusable) thing @@ -88,8 +93,21 @@ struct PortCfg { , std::tuple_size::value >; }; +/** + * @brief This structure provides functions + * that fill inference parameters for "OpenVINO Toolkit" model. + */ template class Params { public: + /** @brief Class constructor. + + Constructs Params based on model information and specifies default values for other + inference description parameters. Model is loaded and compiled using "OpenVINO Toolkit". + + @param model Path to topology IR (.xml file). + @param weights Path to weights (.bin file). + @param device target device to use. + */ Params(const std::string &model, const std::string &weights, const std::string &device) @@ -101,9 +119,17 @@ template class Params { , {} , {} , {} - , 1u} { + , 1u + , {}} { }; + /** @overload + Use this constructor to work with pre-compiled network. + Model is imported from a pre-compiled blob. + + @param model Path to model. + @param device target device to use. + */ Params(const std::string &model, const std::string &device) : desc{ model, {}, device, {}, {}, {} @@ -114,25 +140,57 @@ template class Params { , {} , {} , {} - , 1u} { + , 1u + , {}} { }; - Params& cfgInputLayers(const typename PortCfg::In &ll) { + /** @brief Specifies sequence of network input layers names for inference. + + The function is used to associate cv::gapi::infer<> inputs with the model inputs. + Number of names has to match the number of network inputs as defined in G_API_NET(). + In case a network has only single input layer, there is no need to specify name manually. + + @param layer_names std::array where N is the number of inputs + as defined in the @ref G_API_NET. Contains names of input layers. + @return reference to this parameter structure. + */ + Params& cfgInputLayers(const typename PortCfg::In &layer_names) { desc.input_names.clear(); - desc.input_names.reserve(ll.size()); - std::copy(ll.begin(), ll.end(), + desc.input_names.reserve(layer_names.size()); + std::copy(layer_names.begin(), layer_names.end(), std::back_inserter(desc.input_names)); return *this; } - Params& cfgOutputLayers(const typename PortCfg::Out &ll) { + /** @brief Specifies sequence of network output layers names for inference. + + The function is used to associate cv::gapi::infer<> outputs with the model outputs. + Number of names has to match the number of network outputs as defined in G_API_NET(). + In case a network has only single output layer, there is no need to specify name manually. + + @param layer_names std::array where N is the number of outputs + as defined in the @ref G_API_NET. Contains names of output layers. + @return reference to this parameter structure. + */ + Params& cfgOutputLayers(const typename PortCfg::Out &layer_names) { desc.output_names.clear(); - desc.output_names.reserve(ll.size()); - std::copy(ll.begin(), ll.end(), + desc.output_names.reserve(layer_names.size()); + std::copy(layer_names.begin(), layer_names.end(), std::back_inserter(desc.output_names)); return *this; } + /** @brief Specifies a constant input. + + The function is used to set a constant input. This input has to be + a preprocessed tensor if its type is TENSOR. Need to provide name of the + network layer which will receive provided data. + + @param layer_name Name of network layer. + @param data cv::Mat that contains data which will be associated with network layer. + @param hint Input type @sa cv::gapi::ie::TraitAs. + @return reference to this parameter structure. + */ Params& constInput(const std::string &layer_name, const cv::Mat &data, TraitAs hint = TraitAs::TENSOR) { @@ -140,52 +198,124 @@ template class Params { return *this; } + /** @brief Specifies OpenVINO plugin configuration. + + The function is used to set configuration for OpenVINO plugin. Some parameters + can be different for each plugin. Please follow https://docs.openvinotoolkit.org/latest/index.html + to check information about specific plugin. + + @param cfg Map of pairs: (config parameter name, config parameter value). + @return reference to this parameter structure. + */ + Params& pluginConfig(const IEConfig& cfg) { + desc.config = cfg; + return *this; + } + + /** @overload + Function with a rvalue parameter. + + @param cfg rvalue map of pairs: (config parameter name, config parameter value). + @return reference to this parameter structure. + */ Params& pluginConfig(IEConfig&& cfg) { desc.config = std::move(cfg); return *this; } - Params& pluginConfig(const IEConfig& cfg) { - desc.config = cfg; + /** @brief Specifies configuration for RemoteContext in InferenceEngine. + + When RemoteContext is configured the backend imports the networks using the context. + It also expects cv::MediaFrames to be actually remote, to operate with blobs via the context. + + @param ctx_cfg cv::util::any value which holds InferenceEngine::ParamMap. + @return reference to this parameter structure. + */ + Params& cfgContextParams(const cv::util::any& ctx_cfg) { + desc.context_config = ctx_cfg; return *this; } + /** @overload + Function with an rvalue parameter. + + @param ctx_cfg cv::util::any value which holds InferenceEngine::ParamMap. + @return reference to this parameter structure. + */ + Params& cfgContextParams(cv::util::any&& ctx_cfg) { + desc.context_config = std::move(ctx_cfg); + return *this; + } + + /** @brief Specifies number of asynchronous inference requests. + + @param nireq Number of inference asynchronous requests. + @return reference to this parameter structure. + */ Params& cfgNumRequests(size_t nireq) { GAPI_Assert(nireq > 0 && "Number of infer requests must be greater than zero!"); desc.nireq = nireq; return *this; } - Params& cfgInputReshape(std::map>&& reshape_table) { - desc.reshape_table = std::move(reshape_table); - return *this; - } + /** @brief Specifies new input shapes for the network inputs. + The function is used to specify new input shapes for the network inputs. + Follow https://docs.openvinotoolkit.org/latest/classInferenceEngine_1_1networkNetwork.html + for additional information. + + @param reshape_table Map of pairs: name of corresponding data and its dimension. + @return reference to this parameter structure. + */ Params& cfgInputReshape(const std::map>& reshape_table) { desc.reshape_table = reshape_table; return *this; } - Params& cfgInputReshape(std::string&& layer_name, std::vector&& layer_dims) { - desc.reshape_table.emplace(layer_name, layer_dims); + /** @overload */ + Params& cfgInputReshape(std::map>&& reshape_table) { + desc.reshape_table = std::move(reshape_table); return *this; } + /** @overload + + @param layer_name Name of layer. + @param layer_dims New dimensions for this layer. + @return reference to this parameter structure. + */ Params& cfgInputReshape(const std::string& layer_name, const std::vector& layer_dims) { desc.reshape_table.emplace(layer_name, layer_dims); return *this; } - Params& cfgInputReshape(std::unordered_set&& layer_names) { - desc.layer_names_to_reshape = std::move(layer_names); + /** @overload */ + Params& cfgInputReshape(std::string&& layer_name, std::vector&& layer_dims) { + desc.reshape_table.emplace(layer_name, layer_dims); return *this; } + /** @overload + + @param layer_names set of names of network layers that will be used for network reshape. + @return reference to this parameter structure. + */ Params& cfgInputReshape(const std::unordered_set& layer_names) { desc.layer_names_to_reshape = layer_names; return *this; } + /** @overload + + @param layer_names rvalue set of the selected layers will be reshaped automatically + its input image size. + @return reference to this parameter structure. + */ + Params& cfgInputReshape(std::unordered_set&& layer_names) { + desc.layer_names_to_reshape = std::move(layer_names); + return *this; + } + // BEGIN(G-API's network parametrization API) GBackend backend() const { return cv::gapi::ie::backend(); } std::string tag() const { return Net::tag(); } @@ -196,32 +326,65 @@ template class Params { detail::ParamDesc desc; }; +/* +* @brief This structure provides functions for generic network type that +* fill inference parameters. +* @see struct Generic +*/ template<> class Params { public: + /** @brief Class constructor. + + Constructs Params based on model information and sets default values for other + inference description parameters. Model is loaded and compiled using OpenVINO Toolkit. + + @param tag string tag of the network for which these parameters are intended. + @param model path to topology IR (.xml file). + @param weights path to weights (.bin file). + @param device target device to use. + */ Params(const std::string &tag, const std::string &model, const std::string &weights, const std::string &device) - : desc{ model, weights, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Load, true, {}, {}, {}, 1u}, m_tag(tag) { + : desc{ model, weights, device, {}, {}, {}, 0u, 0u, + detail::ParamDesc::Kind::Load, true, {}, {}, {}, 1u, + {}}, + m_tag(tag) { }; + /** @overload + + This constructor for pre-compiled networks. Model is imported from pre-compiled + blob. + + @param tag string tag of the network for which these parameters are intended. + @param model path to model. + @param device target device to use. + */ Params(const std::string &tag, const std::string &model, const std::string &device) - : desc{ model, {}, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Import, true, {}, {}, {}, 1u}, m_tag(tag) { + : desc{ model, {}, device, {}, {}, {}, 0u, 0u, + detail::ParamDesc::Kind::Import, true, {}, {}, {}, 1u, + {}}, + m_tag(tag) { }; - Params& pluginConfig(IEConfig&& cfg) { - desc.config = std::move(cfg); + /** @see ie::Params::pluginConfig. */ + Params& pluginConfig(const IEConfig& cfg) { + desc.config = cfg; return *this; } - Params& pluginConfig(const IEConfig& cfg) { - desc.config = cfg; + /** @overload */ + Params& pluginConfig(IEConfig&& cfg) { + desc.config = std::move(cfg); return *this; } + /** @see ie::Params::constInput. */ Params& constInput(const std::string &layer_name, const cv::Mat &data, TraitAs hint = TraitAs::TENSOR) { @@ -229,37 +392,44 @@ class Params { return *this; } + /** @see ie::Params::cfgNumRequests. */ Params& cfgNumRequests(size_t nireq) { GAPI_Assert(nireq > 0 && "Number of infer requests must be greater than zero!"); desc.nireq = nireq; return *this; } - Params& cfgInputReshape(std::map> && reshape_table) { - desc.reshape_table = std::move(reshape_table); + /** @see ie::Params::cfgInputReshape */ + Params& cfgInputReshape(const std::map>&reshape_table) { + desc.reshape_table = reshape_table; return *this; } - Params& cfgInputReshape(const std::map>&reshape_table) { - desc.reshape_table = reshape_table; + /** @overload */ + Params& cfgInputReshape(std::map> && reshape_table) { + desc.reshape_table = std::move(reshape_table); return *this; } + /** @overload */ Params& cfgInputReshape(std::string && layer_name, std::vector && layer_dims) { desc.reshape_table.emplace(layer_name, layer_dims); return *this; } + /** @overload */ Params& cfgInputReshape(const std::string & layer_name, const std::vector&layer_dims) { desc.reshape_table.emplace(layer_name, layer_dims); return *this; } + /** @overload */ Params& cfgInputReshape(std::unordered_set && layer_names) { desc.layer_names_to_reshape = std::move(layer_names); return *this; } + /** @overload */ Params& cfgInputReshape(const std::unordered_set&layer_names) { desc.layer_names_to_reshape = layer_names; return *this; diff --git a/modules/gapi/include/opencv2/gapi/infer/onnx.hpp b/modules/gapi/include/opencv2/gapi/infer/onnx.hpp index 3a4e35fb0980..bb5ef6c59e12 100644 --- a/modules/gapi/include/opencv2/gapi/infer/onnx.hpp +++ b/modules/gapi/include/opencv2/gapi/infer/onnx.hpp @@ -2,7 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation #ifndef OPENCV_GAPI_INFER_ONNX_HPP #define OPENCV_GAPI_INFER_ONNX_HPP @@ -20,6 +20,10 @@ namespace cv { namespace gapi { + +/** + * @brief This namespace contains G-API ONNX Runtime backend functions, structures, and symbols. + */ namespace onnx { GAPI_EXPORTS cv::gapi::GBackend backend(); @@ -34,32 +38,35 @@ enum class TraitAs: int { using PostProc = std::function &, std::unordered_map &)>; - namespace detail { +/** +* @brief This structure contains description of inference parameters +* which is specific to ONNX models. +*/ struct ParamDesc { - std::string model_path; + std::string model_path; //!< Path to model. // NB: nun_* may differ from topology's real input/output port numbers // (e.g. topology's partial execution) - std::size_t num_in; // How many inputs are defined in the operation - std::size_t num_out; // How many outputs are defined in the operation + std::size_t num_in; //!< How many inputs are defined in the operation + std::size_t num_out; //!< How many outputs are defined in the operation // NB: Here order follows the `Net` API - std::vector input_names; - std::vector output_names; + std::vector input_names; //!< Names of input network layers. + std::vector output_names; //!< Names of output network layers. using ConstInput = std::pair; - std::unordered_map const_inputs; + std::unordered_map const_inputs; //!< Map with pair of name of network layer and ConstInput which will be associated with this. - std::vector mean; - std::vector stdev; + std::vector mean; //!< Mean values for preprocessing. + std::vector stdev; //!< Standard deviation values for preprocessing. - std::vector out_metas; - PostProc custom_post_proc; + std::vector out_metas; //!< Out meta information about your output (type, dimension). + PostProc custom_post_proc; //!< Post processing function. - std::vector normalize; + std::vector normalize; //!< Vector of bool values that enabled or disabled normalize of input data. - std::vector names_to_remap; + std::vector names_to_remap; //!< Names of output layers that will be processed in PostProc function. }; } // namespace detail @@ -79,30 +86,71 @@ struct PortCfg { , std::tuple_size::value >; }; +/** + * Contains description of inference parameters and kit of functions that + * fill this parameters. + */ template class Params { public: + /** @brief Class constructor. + + Constructs Params based on model information and sets default values for other + inference description parameters. + + @param model Path to model (.onnx file). + */ Params(const std::string &model) { desc.model_path = model; desc.num_in = std::tuple_size::value; desc.num_out = std::tuple_size::value; }; - // BEGIN(G-API's network parametrization API) - GBackend backend() const { return cv::gapi::onnx::backend(); } - std::string tag() const { return Net::tag(); } - cv::util::any params() const { return { desc }; } - // END(G-API's network parametrization API) + /** @brief Specifies sequence of network input layers names for inference. + + The function is used to associate data of graph inputs with input layers of + network topology. Number of names has to match the number of network inputs. If a network + has only one input layer, there is no need to call it as the layer is + associated with input automatically but this doesn't prevent you from + doing it yourself. Count of names has to match to number of network inputs. - Params& cfgInputLayers(const typename PortCfg::In &ll) { - desc.input_names.assign(ll.begin(), ll.end()); + @param layer_names std::array where N is the number of inputs + as defined in the @ref G_API_NET. Contains names of input layers. + @return the reference on modified object. + */ + Params& cfgInputLayers(const typename PortCfg::In &layer_names) { + desc.input_names.assign(layer_names.begin(), layer_names.end()); return *this; } - Params& cfgOutputLayers(const typename PortCfg::Out &ll) { - desc.output_names.assign(ll.begin(), ll.end()); + /** @brief Specifies sequence of output layers names for inference. + + The function is used to associate data of graph outputs with output layers of + network topology. If a network has only one output layer, there is no need to call it + as the layer is associated with ouput automatically but this doesn't prevent + you from doing it yourself. Count of names has to match to number of network + outputs or you can set your own output but for this case you have to + additionally use @ref cfgPostProc function. + + @param layer_names std::array where N is the number of outputs + as defined in the @ref G_API_NET. Contains names of output layers. + @return the reference on modified object. + */ + Params& cfgOutputLayers(const typename PortCfg::Out &layer_names) { + desc.output_names.assign(layer_names.begin(), layer_names.end()); return *this; } + /** @brief Sets a constant input. + + The function is used to set constant input. This input has to be + a prepared tensor since preprocessing is disabled for this case. You should + provide name of network layer which will receive provided data. + + @param layer_name Name of network layer. + @param data cv::Mat that contains data which will be associated with network layer. + @param hint Type of input (TENSOR). + @return the reference on modified object. + */ Params& constInput(const std::string &layer_name, const cv::Mat &data, TraitAs hint = TraitAs::TENSOR) { @@ -110,6 +158,17 @@ template class Params { return *this; } + /** @brief Specifies mean value and standard deviation for preprocessing. + + The function is used to set mean value and standard deviation for preprocessing + of input data. + + @param m std::array where N is the number of inputs + as defined in the @ref G_API_NET. Contains mean values. + @param s std::array where N is the number of inputs + as defined in the @ref G_API_NET. Contains standard deviation values. + @return the reference on modified object. + */ Params& cfgMeanStd(const typename PortCfg::NormCoefs &m, const typename PortCfg::NormCoefs &s) { desc.mean.assign(m.begin(), m.end()); @@ -117,75 +176,103 @@ template class Params { return *this; } - /** @brief Configures graph output and sets the post processing function from user. + /** @brief Configures graph output and provides the post processing function from user. - The function is used for the case of infer of networks with dynamic outputs. - Since these networks haven't known output parameters needs provide them for - construction of output of graph. - The function provides meta information of outputs and post processing function. - Post processing function is used for copy information from ONNX infer's result - to output of graph which is allocated by out meta information. + The function is used when you work with networks with dynamic outputs. + Since we can't know dimensions of inference result needs provide them for + construction of graph output. This dimensions can differ from inference result. + So you have to provide @ref PostProc function that gets information from inference + result and fill output which is constructed by dimensions from out_metas. - @param out_metas out meta information. - @param pp post processing function, which has two parameters. First is onnx + @param out_metas Out meta information about your output (type, dimension). + @param remap_function Post processing function, which has two parameters. First is onnx result, second is graph output. Both parameters is std::map that contain pair of layer's name and cv::Mat. - @return reference to object of class Params. + @return the reference on modified object. */ Params& cfgPostProc(const std::vector &out_metas, - const PostProc &pp) { + const PostProc &remap_function) { desc.out_metas = out_metas; - desc.custom_post_proc = pp; + desc.custom_post_proc = remap_function; return *this; } /** @overload - The function has rvalue parameters. + Function with a rvalue parameters. + + @param out_metas rvalue out meta information about your output (type, dimension). + @param remap_function rvalue post processing function, which has two parameters. First is onnx + result, second is graph output. Both parameters is std::map that contain pair of + layer's name and cv::Mat. + @return the reference on modified object. */ Params& cfgPostProc(std::vector &&out_metas, - PostProc &&pp) { + PostProc &&remap_function) { desc.out_metas = std::move(out_metas); - desc.custom_post_proc = std::move(pp); + desc.custom_post_proc = std::move(remap_function); return *this; } /** @overload The function has additional parameter names_to_remap. This parameter provides - information about output layers which will be used for infer and in post + information about output layers which will be used for inference and post processing function. - @param out_metas out meta information. - @param pp post processing function. - @param names_to_remap contains names of output layers. CNN's infer will be done on these layers. - Infer's result will be processed in post processing function using these names. - @return reference to object of class Params. + @param out_metas Out meta information. + @param remap_function Post processing function. + @param names_to_remap Names of output layers. network's inference will + be done on these layers. Inference's result will be processed in post processing + function using these names. + @return the reference on modified object. */ Params& cfgPostProc(const std::vector &out_metas, - const PostProc &pp, + const PostProc &remap_function, const std::vector &names_to_remap) { desc.out_metas = out_metas; - desc.custom_post_proc = pp; + desc.custom_post_proc = remap_function; desc.names_to_remap = names_to_remap; return *this; } /** @overload - The function has rvalue parameters. + Function with a rvalue parameters and additional parameter names_to_remap. + + @param out_metas rvalue out meta information. + @param remap_function rvalue post processing function. + @param names_to_remap rvalue names of output layers. network's inference will + be done on these layers. Inference's result will be processed in post processing + function using these names. + @return the reference on modified object. */ Params& cfgPostProc(std::vector &&out_metas, - PostProc &&pp, + PostProc &&remap_function, std::vector &&names_to_remap) { desc.out_metas = std::move(out_metas); - desc.custom_post_proc = std::move(pp); + desc.custom_post_proc = std::move(remap_function); desc.names_to_remap = std::move(names_to_remap); return *this; } - Params& cfgNormalize(const typename PortCfg::Normalize &n) { - desc.normalize.assign(n.begin(), n.end()); + /** @brief Specifies normalize parameter for preprocessing. + + The function is used to set normalize parameter for preprocessing of input data. + + @param normalizations std::array where N is the number of inputs + as defined in the @ref G_API_NET. Сontains bool values that enabled or disabled + normalize of input data. + @return the reference on modified object. + */ + Params& cfgNormalize(const typename PortCfg::Normalize &normalizations) { + desc.normalize.assign(normalizations.begin(), normalizations.end()); return *this; } + // BEGIN(G-API's network parametrization API) + GBackend backend() const { return cv::gapi::onnx::backend(); } + std::string tag() const { return Net::tag(); } + cv::util::any params() const { return { desc }; } + // END(G-API's network parametrization API) + protected: detail::ParamDesc desc; }; diff --git a/modules/gapi/include/opencv2/gapi/infer/parsers.hpp b/modules/gapi/include/opencv2/gapi/infer/parsers.hpp index 3225c73831e2..c7308dd39f47 100644 --- a/modules/gapi/include/opencv2/gapi/infer/parsers.hpp +++ b/modules/gapi/include/opencv2/gapi/infer/parsers.hpp @@ -64,12 +64,13 @@ detection is smaller than confidence threshold, detection is rejected. given label will get to the output. @return a tuple with a vector of detected boxes and a vector of appropriate labels. */ -GAPI_EXPORTS std::tuple, GArray> parseSSD(const GMat& in, - const GOpaque& inSz, - const float confidenceThreshold = 0.5f, - const int filterLabel = -1); +GAPI_EXPORTS_W std::tuple, GArray> parseSSD(const GMat& in, + const GOpaque& inSz, + const float confidenceThreshold = 0.5f, + const int filterLabel = -1); + +/** @brief Parses output of SSD network. -/** @overload Extracts detection information (box, confidence) from SSD output and filters it by given confidence and by going out of bounds. @@ -87,9 +88,9 @@ the larger side of the rectangle. */ GAPI_EXPORTS_W GArray parseSSD(const GMat& in, const GOpaque& inSz, - const float confidenceThreshold = 0.5f, - const bool alignmentToSquare = false, - const bool filterOutOfBounds = false); + const float confidenceThreshold, + const bool alignmentToSquare, + const bool filterOutOfBounds); /** @brief Parses output of Yolo network. @@ -112,12 +113,12 @@ If 1.f, nms is not performed and no boxes are rejected. documentation. @return a tuple with a vector of detected boxes and a vector of appropriate labels. */ -GAPI_EXPORTS std::tuple, GArray> parseYolo(const GMat& in, - const GOpaque& inSz, - const float confidenceThreshold = 0.5f, - const float nmsThreshold = 0.5f, - const std::vector& anchors - = nn::parsers::GParseYolo::defaultAnchors()); +GAPI_EXPORTS_W std::tuple, GArray> parseYolo(const GMat& in, + const GOpaque& inSz, + const float confidenceThreshold = 0.5f, + const float nmsThreshold = 0.5f, + const std::vector& anchors + = nn::parsers::GParseYolo::defaultAnchors()); } // namespace gapi } // namespace cv diff --git a/modules/gapi/include/opencv2/gapi/media.hpp b/modules/gapi/include/opencv2/gapi/media.hpp index 3d7f5a5b65e9..aa7d6d6a1f4e 100644 --- a/modules/gapi/include/opencv2/gapi/media.hpp +++ b/modules/gapi/include/opencv2/gapi/media.hpp @@ -13,27 +13,111 @@ #include // forward<>() #include +#include namespace cv { +/** \addtogroup gapi_data_structures + * @{ + * + * @brief Extra G-API data structures used to pass input/output data + * to the graph for processing. + */ +/** + * @brief cv::MediaFrame class represents an image/media frame + * obtained from an external source. + * + * cv::MediaFrame represents image data as specified in + * cv::MediaFormat. cv::MediaFrame is designed to be a thin wrapper over some + * external memory of buffer; the class itself provides an uniform + * interface over such types of memory. cv::MediaFrame wraps data from + * a camera driver or from a media codec and provides an abstraction + * layer over this memory to G-API. MediaFrame defines a compact interface + * to access and manage the underlying data; the implementation is + * fully defined by the associated Adapter (which is usually + * user-defined). + * + * @sa cv::RMat + */ class GAPI_EXPORTS MediaFrame { public: - enum class Access { R, W }; + /// This enum defines different types of cv::MediaFrame provided + /// access to the underlying data. Note that different flags can't + /// be combined in this version. + enum class Access { + R, ///< Access data for reading + W, ///< Access data for writing + }; class IAdapter; class View; using AdapterPtr = std::unique_ptr; + /** + * @brief Constructs an empty MediaFrame + * + * The constructed object has no any data associated with it. + */ MediaFrame(); - explicit MediaFrame(AdapterPtr &&); - template static cv::MediaFrame Create(Args&&...); - View access(Access) const; + /** + * @brief Constructs a MediaFrame with the given + * Adapter. MediaFrame takes ownership over the passed adapter. + * + * @param p an unique pointer to instance of IAdapter derived class. + */ + explicit MediaFrame(AdapterPtr &&p); + + /** + * @overload + * @brief Constructs a MediaFrame with the given parameters for + * the Adapter. The adapter of type `T` is costructed on the fly. + * + * @param args list of arguments to construct an adapter of type + * `T`. + */ + template static cv::MediaFrame Create(Args&&... args); + + /** + * @brief Obtain access to the underlying data with the given + * mode. + * + * Depending on the associated Adapter and the data wrapped, this + * method may be cheap (e.g., the underlying memory is local) or + * costly (if the underlying memory is external or device + * memory). + * + * @param mode an access mode flag + * @return a MediaFrame::View object. The views should be handled + * carefully, refer to the MediaFrame::View documentation for details. + */ + View access(Access mode) const; + + /** + * @brief Returns a media frame descriptor -- the information + * about the media format, dimensions, etc. + * @return a cv::GFrameDesc + */ cv::GFrameDesc desc() const; - // Cast underlying MediaFrame adapter to the particular adapter type, - // return nullptr if underlying type is different - template T* get() const - { + // FIXME: design a better solution + // Should be used only if the actual adapter provides implementation + /// @private -- exclude from the OpenCV documentation for now. + cv::util::any blobParams() const; + + /** + * @brief Casts and returns the associated MediaFrame adapter to + * the particular adapter type `T`, returns nullptr if the type is + * different. + * + * This method may be useful if the adapter type is known by the + * caller, and some lower level access to the memory is required. + * Depending on the memory type, it may be more efficient than + * access(). + * + * @return a pointer to the adapter object, nullptr if the adapter + * type is different. + */ + template T* get() const { static_assert(std::is_base_of::value, "T is not derived from cv::MediaFrame::IAdapter!"); auto* adapter = getAdapter(); @@ -53,6 +137,43 @@ inline cv::MediaFrame cv::MediaFrame::Create(Args&&... args) { return cv::MediaFrame(std::move(ptr)); } +/** + * @brief Provides access to the MediaFrame's underlying data. + * + * This object contains the necessary information to access the pixel + * data of the associated MediaFrame: arrays of pointers and strides + * (distance between every plane row, in bytes) for every image + * plane, as defined in cv::MediaFormat. + * There may be up to four image planes in MediaFrame. + * + * Depending on the MediaFrame::Access flag passed in + * MediaFrame::access(), a MediaFrame::View may be read- or + * write-only. + * + * Depending on the MediaFrame::IAdapter implementation associated + * with the parent MediaFrame, writing to memory with + * MediaFrame::Access::R flag may have no effect or lead to + * undefined behavior. Same applies to reading the memory with + * MediaFrame::Access::W flag -- again, depending on the IAdapter + * implementation, the host-side buffer the view provides access to + * may have no current data stored in (so in-place editing of the + * buffer contents may not be possible). + * + * MediaFrame::View objects must be handled carefully, as an external + * resource associated with MediaFrame may be locked for the time the + * MediaFrame::View object exists. Obtaining MediaFrame::View should + * be seen as "map" and destroying it as "unmap" in the "map/unmap" + * idiom (applicable to OpenCL, device memory, remote + * memory). + * + * When a MediaFrame buffer is accessed for writing, and the memory + * under MediaFrame::View::Ptrs is altered, the data synchronization + * of a host-side and device/remote buffer is not guaranteed until the + * MediaFrame::View is destroyed. In other words, the real data on the + * device or in a remote target may be updated at the MediaFrame::View + * destruction only -- but it depends on the associated + * MediaFrame::IAdapter implementation. + */ class GAPI_EXPORTS MediaFrame::View final { public: static constexpr const size_t MAX_PLANES = 4; @@ -60,25 +181,48 @@ class GAPI_EXPORTS MediaFrame::View final { using Strides = std::array; // in bytes using Callback = std::function; + /// @private View(Ptrs&& ptrs, Strides&& strs, Callback &&cb = [](){}); + + /// @private View(const View&) = delete; + + /// @private View(View&&) = default; + + /// @private View& operator = (const View&) = delete; + ~View(); - Ptrs ptr; - Strides stride; + Ptrs ptr; ///< Array of image plane pointers + Strides stride; ///< Array of image plane strides, in bytes. private: Callback m_cb; }; +/** + * @brief An interface class for MediaFrame data adapters. + * + * Implement this interface to wrap media data in the MediaFrame. It + * makes sense to implement this class if there is a custom + * cv::gapi::wip::IStreamSource defined -- in this case, a stream + * source can produce MediaFrame objects with this adapter and the + * media data may be passed to graph without any copy. For example, a + * GStreamer-based stream source can implement an adapter over + * `GstBuffer` and G-API will transparently use it in the graph. + */ class GAPI_EXPORTS MediaFrame::IAdapter { public: virtual ~IAdapter() = 0; virtual cv::GFrameDesc meta() const = 0; virtual MediaFrame::View access(MediaFrame::Access) = 0; + // FIXME: design a better solution + // The default implementation does nothing + virtual cv::util::any blobParams() const; }; +/** @} */ } //namespace cv diff --git a/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp b/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp index 8ec388d588b1..6a2f1df769b9 100644 --- a/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp @@ -29,6 +29,9 @@ namespace gimpl namespace gapi { +/** + * @brief This namespace contains G-API OpenCL backend functions, structures, and symbols. + */ namespace ocl { /** diff --git a/modules/gapi/include/opencv2/gapi/own/exports.hpp b/modules/gapi/include/opencv2/gapi/own/exports.hpp index 1978991b7518..c36f4003d0fb 100644 --- a/modules/gapi/include/opencv2/gapi/own/exports.hpp +++ b/modules/gapi/include/opencv2/gapi/own/exports.hpp @@ -13,11 +13,13 @@ # define GAPI_EXPORTS CV_EXPORTS /* special informative macros for wrapper generators */ # define GAPI_PROP CV_PROP +# define GAPI_PROP_RW CV_PROP_RW # define GAPI_WRAP CV_WRAP # define GAPI_EXPORTS_W_SIMPLE CV_EXPORTS_W_SIMPLE # define GAPI_EXPORTS_W CV_EXPORTS_W # else # define GAPI_PROP +# define GAPI_PROP_RW # define GAPI_WRAP # define GAPI_EXPORTS # define GAPI_EXPORTS_W_SIMPLE diff --git a/modules/gapi/include/opencv2/gapi/own/types.hpp b/modules/gapi/include/opencv2/gapi/own/types.hpp index c77a62ca537f..53bb867e32f9 100644 --- a/modules/gapi/include/opencv2/gapi/own/types.hpp +++ b/modules/gapi/include/opencv2/gapi/own/types.hpp @@ -15,6 +15,11 @@ namespace cv { namespace gapi { + +/** + * @brief This namespace contains G-API own data structures used in + * its standalone mode build. + */ namespace own { diff --git a/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp b/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp index bd12d2583287..3207a8cb2e44 100644 --- a/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp +++ b/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp @@ -15,6 +15,11 @@ namespace cv { namespace gapi { + +/** + * @brief This namespace contains G-API PlaidML backend functions, + * structures, and symbols. + */ namespace plaidml { diff --git a/modules/gapi/include/opencv2/gapi/python/python.hpp b/modules/gapi/include/opencv2/gapi/python/python.hpp index 1c85d69d9f65..0e20bbbb595f 100644 --- a/modules/gapi/include/opencv2/gapi/python/python.hpp +++ b/modules/gapi/include/opencv2/gapi/python/python.hpp @@ -13,6 +13,15 @@ namespace cv { namespace gapi { + +/** + * @brief This namespace contains G-API Python backend functions, + * structures, and symbols. + * + * This functionality is required to enable G-API custom operations + * and kernels when using G-API from Python, no need to use it in the + * C++ form. + */ namespace python { GAPI_EXPORTS cv::gapi::GBackend backend(); diff --git a/modules/gapi/include/opencv2/gapi/render/render.hpp b/modules/gapi/include/opencv2/gapi/render/render.hpp index a84c26c8103e..537541222414 100644 --- a/modules/gapi/include/opencv2/gapi/render/render.hpp +++ b/modules/gapi/include/opencv2/gapi/render/render.hpp @@ -81,9 +81,9 @@ using GMatDesc2 = std::tuple; @param prims vector of drawing primitivies @param args graph compile time parameters */ -void GAPI_EXPORTS render(cv::Mat& bgr, - const Prims& prims, - cv::GCompileArgs&& args = {}); +void GAPI_EXPORTS_W render(cv::Mat& bgr, + const Prims& prims, + cv::GCompileArgs&& args = {}); /** @brief The function renders on two NV12 planes passed drawing primitivies @@ -92,10 +92,10 @@ void GAPI_EXPORTS render(cv::Mat& bgr, @param prims vector of drawing primitivies @param args graph compile time parameters */ -void GAPI_EXPORTS render(cv::Mat& y_plane, - cv::Mat& uv_plane, - const Prims& prims, - cv::GCompileArgs&& args = {}); +void GAPI_EXPORTS_W render(cv::Mat& y_plane, + cv::Mat& uv_plane, + const Prims& prims, + cv::GCompileArgs&& args = {}); /** @brief The function renders on the input media frame passed drawing primitivies @@ -139,7 +139,7 @@ Output image must be 8-bit unsigned planar 3-channel image @param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3 @param prims draw primitives */ -GAPI_EXPORTS GMat render3ch(const GMat& src, const GArray& prims); +GAPI_EXPORTS_W GMat render3ch(const GMat& src, const GArray& prims); /** @brief Renders on two planes @@ -150,9 +150,9 @@ uv image must be 8-bit unsigned planar 2-channel image @ref CV_8UC2 @param uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2 @param prims draw primitives */ -GAPI_EXPORTS GMat2 renderNV12(const GMat& y, - const GMat& uv, - const GArray& prims); +GAPI_EXPORTS_W GMat2 renderNV12(const GMat& y, + const GMat& uv, + const GArray& prims); /** @brief Renders Media Frame @@ -169,11 +169,15 @@ GAPI_EXPORTS GFrame renderFrame(const GFrame& m_frame, } // namespace draw } // namespace wip +/** + * @brief This namespace contains G-API CPU rendering backend functions, + * structures, and symbols. See @ref gapi_draw for details. + */ namespace render { namespace ocv { - GAPI_EXPORTS cv::gapi::GKernelPackage kernels(); + GAPI_EXPORTS_W cv::gapi::GKernelPackage kernels(); } // namespace ocv } // namespace render diff --git a/modules/gapi/include/opencv2/gapi/render/render_types.hpp b/modules/gapi/include/opencv2/gapi/render/render_types.hpp index ca403be361ee..6d70e3a877dd 100644 --- a/modules/gapi/include/opencv2/gapi/render/render_types.hpp +++ b/modules/gapi/include/opencv2/gapi/render/render_types.hpp @@ -41,7 +41,7 @@ struct freetype_font * * Parameters match cv::putText(). */ -struct Text +struct GAPI_EXPORTS_W_SIMPLE Text { /** * @brief Text constructor @@ -55,6 +55,7 @@ struct Text * @param lt_ The line type. See #LineTypes * @param bottom_left_origin_ When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner */ + GAPI_WRAP Text(const std::string& text_, const cv::Point& org_, int ff_, @@ -68,17 +69,18 @@ struct Text { } + GAPI_WRAP Text() = default; /*@{*/ - std::string text; //!< The text string to be drawn - cv::Point org; //!< The bottom-left corner of the text string in the image - int ff; //!< The font type, see #HersheyFonts - double fs; //!< The font scale factor that is multiplied by the font-specific base size - cv::Scalar color; //!< The text color - int thick; //!< The thickness of the lines used to draw a text - int lt; //!< The line type. See #LineTypes - bool bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner + GAPI_PROP_RW std::string text; //!< The text string to be drawn + GAPI_PROP_RW cv::Point org; //!< The bottom-left corner of the text string in the image + GAPI_PROP_RW int ff; //!< The font type, see #HersheyFonts + GAPI_PROP_RW double fs; //!< The font scale factor that is multiplied by the font-specific base size + GAPI_PROP_RW cv::Scalar color; //!< The text color + GAPI_PROP_RW int thick; //!< The thickness of the lines used to draw a text + GAPI_PROP_RW int lt; //!< The line type. See #LineTypes + GAPI_PROP_RW bool bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner /*@{*/ }; @@ -122,7 +124,7 @@ struct FText * * Parameters match cv::rectangle(). */ -struct Rect +struct GAPI_EXPORTS_W_SIMPLE Rect { /** * @brief Rect constructor @@ -142,14 +144,15 @@ struct Rect { } + GAPI_WRAP Rect() = default; /*@{*/ - cv::Rect rect; //!< Coordinates of the rectangle - cv::Scalar color; //!< The rectangle color or brightness (grayscale image) - int thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle - int lt; //!< The type of the line. See #LineTypes - int shift; //!< The number of fractional bits in the point coordinates + GAPI_PROP_RW cv::Rect rect; //!< Coordinates of the rectangle + GAPI_PROP_RW cv::Scalar color; //!< The rectangle color or brightness (grayscale image) + GAPI_PROP_RW int thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle + GAPI_PROP_RW int lt; //!< The type of the line. See #LineTypes + GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinates /*@{*/ }; @@ -158,7 +161,7 @@ struct Rect * * Parameters match cv::circle(). */ -struct Circle +struct GAPI_EXPORTS_W_SIMPLE Circle { /** * @brief Circle constructor @@ -170,6 +173,7 @@ struct Circle * @param lt_ The Type of the circle boundary. See #LineTypes * @param shift_ The Number of fractional bits in the coordinates of the center and in the radius value */ + GAPI_WRAP Circle(const cv::Point& center_, int radius_, const cv::Scalar& color_, @@ -180,15 +184,16 @@ struct Circle { } + GAPI_WRAP Circle() = default; /*@{*/ - cv::Point center; //!< The center of the circle - int radius; //!< The radius of the circle - cv::Scalar color; //!< The color of the circle - int thick; //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn - int lt; //!< The Type of the circle boundary. See #LineTypes - int shift; //!< The Number of fractional bits in the coordinates of the center and in the radius value + GAPI_PROP_RW cv::Point center; //!< The center of the circle + GAPI_PROP_RW int radius; //!< The radius of the circle + GAPI_PROP_RW cv::Scalar color; //!< The color of the circle + GAPI_PROP_RW int thick; //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn + GAPI_PROP_RW int lt; //!< The Type of the circle boundary. See #LineTypes + GAPI_PROP_RW int shift; //!< The Number of fractional bits in the coordinates of the center and in the radius value /*@{*/ }; @@ -197,7 +202,7 @@ struct Circle * * Parameters match cv::line(). */ -struct Line +struct GAPI_EXPORTS_W_SIMPLE Line { /** * @brief Line constructor @@ -209,6 +214,7 @@ struct Line * @param lt_ The Type of the line. See #LineTypes * @param shift_ The number of fractional bits in the point coordinates */ + GAPI_WRAP Line(const cv::Point& pt1_, const cv::Point& pt2_, const cv::Scalar& color_, @@ -219,15 +225,16 @@ struct Line { } + GAPI_WRAP Line() = default; /*@{*/ - cv::Point pt1; //!< The first point of the line segment - cv::Point pt2; //!< The second point of the line segment - cv::Scalar color; //!< The line color - int thick; //!< The thickness of line - int lt; //!< The Type of the line. See #LineTypes - int shift; //!< The number of fractional bits in the point coordinates + GAPI_PROP_RW cv::Point pt1; //!< The first point of the line segment + GAPI_PROP_RW cv::Point pt2; //!< The second point of the line segment + GAPI_PROP_RW cv::Scalar color; //!< The line color + GAPI_PROP_RW int thick; //!< The thickness of line + GAPI_PROP_RW int lt; //!< The Type of the line. See #LineTypes + GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinates /*@{*/ }; @@ -236,7 +243,7 @@ struct Line * * Mosaicing is a very basic method to obfuscate regions in the image. */ -struct Mosaic +struct GAPI_EXPORTS_W_SIMPLE Mosaic { /** * @brief Mosaic constructor @@ -252,12 +259,13 @@ struct Mosaic { } + GAPI_WRAP Mosaic() : cellSz(0), decim(0) {} /*@{*/ - cv::Rect mos; //!< Coordinates of the mosaic - int cellSz; //!< Cell size (same for X, Y) - int decim; //!< Decimation (0 stands for no decimation) + GAPI_PROP_RW cv::Rect mos; //!< Coordinates of the mosaic + GAPI_PROP_RW int cellSz; //!< Cell size (same for X, Y) + GAPI_PROP_RW int decim; //!< Decimation (0 stands for no decimation) /*@{*/ }; @@ -266,7 +274,7 @@ struct Mosaic * * Image is blended on a frame using the specified mask. */ -struct Image +struct GAPI_EXPORTS_W_SIMPLE Image { /** * @brief Mosaic constructor @@ -275,6 +283,7 @@ struct Image * @param img_ Image to draw * @param alpha_ Alpha channel for image to draw (same size and number of channels) */ + GAPI_WRAP Image(const cv::Point& org_, const cv::Mat& img_, const cv::Mat& alpha_) : @@ -282,19 +291,20 @@ struct Image { } + GAPI_WRAP Image() = default; /*@{*/ - cv::Point org; //!< The bottom-left corner of the image - cv::Mat img; //!< Image to draw - cv::Mat alpha; //!< Alpha channel for image to draw (same size and number of channels) + GAPI_PROP_RW cv::Point org; //!< The bottom-left corner of the image + GAPI_PROP_RW cv::Mat img; //!< Image to draw + GAPI_PROP_RW cv::Mat alpha; //!< Alpha channel for image to draw (same size and number of channels) /*@{*/ }; /** * @brief This structure represents a polygon to draw. */ -struct Poly +struct GAPI_EXPORTS_W_SIMPLE Poly { /** * @brief Mosaic constructor @@ -305,6 +315,7 @@ struct Poly * @param lt_ The Type of the line. See #LineTypes * @param shift_ The number of fractional bits in the point coordinate */ + GAPI_WRAP Poly(const std::vector& points_, const cv::Scalar& color_, int thick_ = 1, @@ -314,14 +325,15 @@ struct Poly { } + GAPI_WRAP Poly() = default; /*@{*/ - std::vector points; //!< Points to connect - cv::Scalar color; //!< The line color - int thick; //!< The thickness of line - int lt; //!< The Type of the line. See #LineTypes - int shift; //!< The number of fractional bits in the point coordinate + GAPI_PROP_RW std::vector points; //!< Points to connect + GAPI_PROP_RW cv::Scalar color; //!< The line color + GAPI_PROP_RW int thick; //!< The thickness of line + GAPI_PROP_RW int lt; //!< The Type of the line. See #LineTypes + GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinate /*@{*/ }; @@ -336,7 +348,7 @@ using Prim = util::variant , Poly >; -using Prims = std::vector; +using Prims = std::vector; //! @} gapi_draw_prims } // namespace draw diff --git a/modules/gapi/include/opencv2/gapi/rmat.hpp b/modules/gapi/include/opencv2/gapi/rmat.hpp index f50bd08b6506..cc27f48664cd 100644 --- a/modules/gapi/include/opencv2/gapi/rmat.hpp +++ b/modules/gapi/include/opencv2/gapi/rmat.hpp @@ -42,6 +42,9 @@ namespace cv { // performCalculations(in_view, out_view); // // data from out_view is transferred to the device when out_view is destroyed // } +/** \addtogroup gapi_data_structures + * @{ + */ class GAPI_EXPORTS RMat { public: @@ -146,6 +149,7 @@ class GAPI_EXPORTS RMat template RMat make_rmat(Ts&&... args) { return { std::make_shared(std::forward(args)...) }; } +/** @} */ } //namespace cv diff --git a/modules/gapi/include/opencv2/gapi/s11n.hpp b/modules/gapi/include/opencv2/gapi/s11n.hpp index 5a64410e5abe..ca8e32c98bf9 100644 --- a/modules/gapi/include/opencv2/gapi/s11n.hpp +++ b/modules/gapi/include/opencv2/gapi/s11n.hpp @@ -17,65 +17,135 @@ namespace cv { namespace gapi { +/** +* \addtogroup gapi_serialization +* @{ +*/ + namespace detail { - GAPI_EXPORTS cv::GComputation getGraph(const std::vector &p); + GAPI_EXPORTS cv::GComputation getGraph(const std::vector &bytes); - GAPI_EXPORTS cv::GMetaArgs getMetaArgs(const std::vector &p); + GAPI_EXPORTS cv::GMetaArgs getMetaArgs(const std::vector &bytes); - GAPI_EXPORTS cv::GRunArgs getRunArgs(const std::vector &p); + GAPI_EXPORTS cv::GRunArgs getRunArgs(const std::vector &bytes); - GAPI_EXPORTS std::vector getVectorOfStrings(const std::vector &p); + GAPI_EXPORTS std::vector getVectorOfStrings(const std::vector &bytes); template - cv::GCompileArgs getCompileArgs(const std::vector &p); + cv::GCompileArgs getCompileArgs(const std::vector &bytes); template - cv::GRunArgs getRunArgsWithRMats(const std::vector &p); + cv::GRunArgs getRunArgsWithRMats(const std::vector &bytes); } // namespace detail +/** @brief Serialize a graph represented by GComputation into an array of bytes. + * + * Check different overloads for more examples. + * @param c GComputation to serialize. + * @return serialized vector of bytes. + */ GAPI_EXPORTS std::vector serialize(const cv::GComputation &c); -//namespace{ +/** @overload + * @param ca GCompileArgs to serialize. + */ +GAPI_EXPORTS std::vector serialize(const cv::GCompileArgs& ca); + +/** @overload + * @param ma GMetaArgs to serialize. + */ +GAPI_EXPORTS std::vector serialize(const cv::GMetaArgs& ma); + +/** @overload + * @param ra GRunArgs to serialize. + */ +GAPI_EXPORTS std::vector serialize(const cv::GRunArgs& ra); + +/** @overload + * @param vs std::vector to serialize. + */ +GAPI_EXPORTS std::vector serialize(const std::vector& vs); + +/** + * @private + */ template static inline -T deserialize(const std::vector &p); - -//} //ananymous namespace - -GAPI_EXPORTS std::vector serialize(const cv::GCompileArgs&); -GAPI_EXPORTS std::vector serialize(const cv::GMetaArgs&); -GAPI_EXPORTS std::vector serialize(const cv::GRunArgs&); -GAPI_EXPORTS std::vector serialize(const std::vector&); - +T deserialize(const std::vector &bytes); + +/** @brief Deserialize GComputation from a byte array. + * + * Check different overloads for more examples. + * @param bytes serialized vector of bytes. + * @return deserialized GComputation object. + */ template<> inline -cv::GComputation deserialize(const std::vector &p) { - return detail::getGraph(p); +cv::GComputation deserialize(const std::vector &bytes) { + return detail::getGraph(bytes); } +/** @brief Deserialize GMetaArgs from a byte array. + * + * Check different overloads for more examples. + * @param bytes serialized vector of bytes. + * @return deserialized GMetaArgs object. + */ template<> inline -cv::GMetaArgs deserialize(const std::vector &p) { - return detail::getMetaArgs(p); +cv::GMetaArgs deserialize(const std::vector &bytes) { + return detail::getMetaArgs(bytes); } +/** @brief Deserialize GRunArgs from a byte array. + * + * Check different overloads for more examples. + * @param bytes serialized vector of bytes. + * @return deserialized GRunArgs object. + */ template<> inline -cv::GRunArgs deserialize(const std::vector &p) { - return detail::getRunArgs(p); +cv::GRunArgs deserialize(const std::vector &bytes) { + return detail::getRunArgs(bytes); } +/** @brief Deserialize std::vector from a byte array. + * + * Check different overloads for more examples. + * @param bytes serialized vector of bytes. + * @return deserialized std::vector object. + */ template<> inline -std::vector deserialize(const std::vector &p) { - return detail::getVectorOfStrings(p); +std::vector deserialize(const std::vector &bytes) { + return detail::getVectorOfStrings(bytes); } +/** + * @brief Deserialize GCompileArgs which types were specified in the template from a byte array. + * + * @note cv::gapi::s11n::detail::S11N template specialization must be provided to make a custom type + * in GCompileArgs deserializable. + * + * @param bytes vector of bytes to deserialize GCompileArgs object from. + * @return GCompileArgs object. + * @see GCompileArgs cv::gapi::s11n::detail::S11N + */ template inline typename std::enable_if::value, GCompileArgs>:: -type deserialize(const std::vector &p) { - return detail::getCompileArgs(p); +type deserialize(const std::vector &bytes) { + return detail::getCompileArgs(bytes); } +/** + * @brief Deserialize GRunArgs including RMat objects if any from a byte array. + * + * RMat adapter type is specified in the template. + * @note To be used properly specified adapter type must overload its serialize() and + * deserialize() methods. + * @param bytes vector of bytes to deserialize GRunArgs object from. + * @return GRunArgs including RMat objects if any. + * @see RMat + */ template inline typename std::enable_if::value, GRunArgs>:: -type deserialize(const std::vector &p) { - return detail::getRunArgsWithRMats(p); +type deserialize(const std::vector &bytes) { + return detail::getRunArgsWithRMats(bytes); } } // namespace gapi } // namespace cv @@ -83,6 +153,17 @@ type deserialize(const std::vector &p) { namespace cv { namespace gapi { namespace s11n { + +/** @brief This structure is an interface for serialization routines. + * + * It's main purpose is to provide multiple overloads for operator<<() + * with basic C++ in addition to OpenCV/G-API types. + * + * This sctructure can be inherited and further extended with additional types. + * + * For example, it is utilized in cv::gapi::s11n::detail::S11N as input parameter + * in serialize() method. + */ struct GAPI_EXPORTS IOStream { virtual ~IOStream() = default; // Define the native support for basic C++ types at the API level: @@ -99,6 +180,16 @@ struct GAPI_EXPORTS IOStream { virtual IOStream& operator<< (const std::string&) = 0; }; +/** @brief This structure is an interface for deserialization routines. + * + * It's main purpose is to provide multiple overloads for operator>>() + * with basic C++ in addition to OpenCV/G-API types. + * + * This structure can be inherited and further extended with additional types. + * + * For example, it is utilized in cv::gapi::s11n::detail::S11N as input parameter + * in deserialize() method. + */ struct GAPI_EXPORTS IIStream { virtual ~IIStream() = default; virtual IIStream& operator>> (bool &) = 0; @@ -116,7 +207,7 @@ struct GAPI_EXPORTS IIStream { }; namespace detail { -GAPI_EXPORTS std::unique_ptr getInStream(const std::vector &p); +GAPI_EXPORTS std::unique_ptr getInStream(const std::vector &bytes); } // namespace detail //////////////////////////////////////////////////////////////////////////////// @@ -146,24 +237,26 @@ GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Mat &m); // FIXME: for GRunArgs serailization #if !defined(GAPI_STANDALONE) -GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::UMat &); -GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::UMat &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::UMat & um); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::UMat & um); #endif // !defined(GAPI_STANDALONE) GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::RMat &r); GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::RMat &r); -GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &); -GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &issptr); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &issptr); -GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::VectorRef &); -GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::VectorRef &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::VectorRef &vr); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::VectorRef &vr); -GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::OpaqueRef &); -GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::OpaqueRef &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::OpaqueRef &opr); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::OpaqueRef &opr); -GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::MediaFrame &); -GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::MediaFrame &); +/// @private -- Exclude this function from OpenCV documentation +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::MediaFrame &mf); +/// @private -- Exclude this function from OpenCV documentation +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::MediaFrame &mf); // Generic STL types //////////////////////////////////////////////////////////////// template @@ -186,6 +279,7 @@ IIStream& operator>> (IIStream& is, std::map &m) { } return is; } + template IOStream& operator<< (IOStream& os, const std::unordered_map &m) { const uint32_t sz = static_cast(m.size()); @@ -206,6 +300,7 @@ IIStream& operator>> (IIStream& is, std::unordered_map &m) { } return is; } + template IOStream& operator<< (IOStream& os, const std::vector &ts) { const uint32_t sz = static_cast(ts.size()); @@ -233,16 +328,19 @@ template IOStream& put_v(IOStream&, const V&, std::size_t) { GAPI_Assert(false && "variant>>: requested index is invalid"); }; + template IOStream& put_v(IOStream& os, const V& v, std::size_t x) { return (x == 0u) ? os << cv::util::get(v) : put_v(os, v, x-1); } + template IIStream& get_v(IIStream&, V&, std::size_t, std::size_t) { GAPI_Assert(false && "variant<<: requested index is invalid"); } + template IIStream& get_v(IIStream& is, V& v, std::size_t i, std::size_t gi) { if (i == gi) { @@ -254,11 +352,13 @@ IIStream& get_v(IIStream& is, V& v, std::size_t i, std::size_t gi) { } } // namespace detail +//! @overload template IOStream& operator<< (IOStream& os, const cv::util::variant &v) { os << static_cast(v.index()); return detail::put_v, Ts...>(os, v, v.index()); } +//! @overload template IIStream& operator>> (IIStream& is, cv::util::variant &v) { int idx = -1; @@ -268,6 +368,7 @@ IIStream& operator>> (IIStream& is, cv::util::variant &v) { } // FIXME: consider a better solution +/// @private -- Exclude this function from OpenCV documentation template void getRunArgByIdx (IIStream& is, cv::util::variant &v, uint32_t idx) { is = detail::get_v, Ts...>(is, v, 0u, idx); @@ -351,8 +452,8 @@ cv::GCompileArgs getCompileArgs(const std::vector &sArgs) { } template -cv::GRunArgs getRunArgsWithRMats(const std::vector &p) { - std::unique_ptr pIs = cv::gapi::s11n::detail::getInStream(p); +cv::GRunArgs getRunArgsWithRMats(const std::vector &bytes) { + std::unique_ptr pIs = cv::gapi::s11n::detail::getInStream(bytes); cv::gapi::s11n::IIStream& is = *pIs; cv::GRunArgs args; @@ -367,6 +468,8 @@ cv::GRunArgs getRunArgsWithRMats(const std::vector &p) { return args; } } // namespace detail +/** @} */ + } // namespace gapi } // namespace cv diff --git a/modules/gapi/include/opencv2/gapi/s11n/base.hpp b/modules/gapi/include/opencv2/gapi/s11n/base.hpp index d9335ee9f7ce..11440b27e5f8 100644 --- a/modules/gapi/include/opencv2/gapi/s11n/base.hpp +++ b/modules/gapi/include/opencv2/gapi/s11n/base.hpp @@ -2,7 +2,7 @@ // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // -// Copyright (C) 2020 Intel Corporation +// Copyright (C) 2020-2021 Intel Corporation #ifndef OPENCV_GAPI_S11N_BASE_HPP #define OPENCV_GAPI_S11N_BASE_HPP @@ -12,31 +12,65 @@ namespace cv { namespace gapi { + +/** + * @brief This namespace contains G-API serialization and + * deserialization functions and data structures. + */ namespace s11n { struct IOStream; struct IIStream; namespace detail { +//! @addtogroup gapi_serialization +//! @{ + struct NotImplemented { }; -// The default S11N for custom types is NotImplemented -// Don't! sublass from NotImplemented if you actually implement S11N. +/** @brief This structure allows to implement serialization routines for custom types. + * + * The default S11N for custom types is not implemented. + * + * @note When providing an overloaded implementation for S11N with your type + * don't inherit it from NotImplemented structure. + * + * @note There are lots of overloaded >> and << operators for basic and OpenCV/G-API types + * which can be utilized when serializing a custom type. + * + * Example of usage: + * @snippet modules/gapi/samples/api_ref_snippets.cpp S11N usage + * + */ template struct S11N: public NotImplemented { + /** + * @brief This function allows user to serialize their custom type. + * + * @note The default overload throws an exception if called. User need to + * properly overload the function to use it. + */ static void serialize(IOStream &, const T &) { GAPI_Assert(false && "No serialization routine is provided!"); } + /** + * @brief This function allows user to deserialize their custom type. + * + * @note The default overload throws an exception if called. User need to + * properly overload the function to use it. + */ static T deserialize(IIStream &) { GAPI_Assert(false && "No deserialization routine is provided!"); } }; +/// @private -- Exclude this struct from OpenCV documentation template struct has_S11N_spec { static constexpr bool value = !std::is_base_of::type>>::value; }; +//! @} gapi_serialization } // namespace detail } // namespace s11n diff --git a/modules/gapi/include/opencv2/gapi/stereo.hpp b/modules/gapi/include/opencv2/gapi/stereo.hpp index 908045d4c779..dcf8f4d26011 100644 --- a/modules/gapi/include/opencv2/gapi/stereo.hpp +++ b/modules/gapi/include/opencv2/gapi/stereo.hpp @@ -14,13 +14,35 @@ namespace cv { namespace gapi { +/** + * The enum specified format of result that you get from @ref cv::gapi::stereo. + */ enum class StereoOutputFormat { - DEPTH_FLOAT16, - DEPTH_FLOAT32, - DISPARITY_FIXED16_11_5, - DISPARITY_FIXED16_12_4 + DEPTH_FLOAT16, ///< Floating point 16 bit value, CV_16FC1. + ///< This identifier is deprecated, use DEPTH_16F instead. + DEPTH_FLOAT32, ///< Floating point 32 bit value, CV_32FC1 + ///< This identifier is deprecated, use DEPTH_16F instead. + DISPARITY_FIXED16_11_5, ///< 16 bit signed: first bit for sign, + ///< 10 bits for integer part, + ///< 5 bits for fractional part. + ///< This identifier is deprecated, + ///< use DISPARITY_16Q_10_5 instead. + DISPARITY_FIXED16_12_4, ///< 16 bit signed: first bit for sign, + ///< 11 bits for integer part, + ///< 4 bits for fractional part. + ///< This identifier is deprecated, + ///< use DISPARITY_16Q_11_4 instead. + DEPTH_16F = DEPTH_FLOAT16, ///< Same as DEPTH_FLOAT16 + DEPTH_32F = DEPTH_FLOAT32, ///< Same as DEPTH_FLOAT32 + DISPARITY_16Q_10_5 = DISPARITY_FIXED16_11_5, ///< Same as DISPARITY_FIXED16_11_5 + DISPARITY_16Q_11_4 = DISPARITY_FIXED16_12_4 ///< Same as DISPARITY_FIXED16_12_4 }; + +/** + * @brief This namespace contains G-API Operation Types for Stereo and + * related functionality. + */ namespace calib3d { G_TYPED_KERNEL(GStereo, , "org.opencv.stereo") { @@ -47,13 +69,12 @@ G_TYPED_KERNEL(GStereo, , "org.openc } // namespace calib3d -/** @brief Extract disparity/depth information depending on passed StereoOutputFormat argument. -The function extracts disparity/depth information depending on passed StereoOutputFormat argument from -given stereo-pair. +/** @brief Computes disparity/depth map for the specified stereo-pair. +The function computes disparity or depth map depending on passed StereoOutputFormat argument. -@param left left 8-bit unsigned 1-channel image of @ref CV_8UC1 type -@param right right 8-bit unsigned 1-channel image of @ref CV_8UC1 type -@param of enum to specify output kind: depth or disparity and corresponding type +@param left 8-bit single-channel left image of @ref CV_8UC1 type. +@param right 8-bit single-channel right image of @ref CV_8UC1 type. +@param of enum to specified output kind: depth or disparity and corresponding type */ GAPI_EXPORTS GMat stereo(const GMat& left, const GMat& right, diff --git a/modules/gapi/include/opencv2/gapi/streaming/format.hpp b/modules/gapi/include/opencv2/gapi/streaming/format.hpp index c9d2fa3e0a29..f7c3bd457dfb 100644 --- a/modules/gapi/include/opencv2/gapi/streaming/format.hpp +++ b/modules/gapi/include/opencv2/gapi/streaming/format.hpp @@ -74,7 +74,7 @@ e.g when graph's input needs to be passed directly to output, like in Streaming @param in Input image @return Copy of the input */ -GAPI_EXPORTS GMat copy(const GMat& in); +GAPI_EXPORTS_W GMat copy(const GMat& in); /** @brief Makes a copy of the input frame. Note that this copy may be not real (no actual data copied). Use this function to maintain graph contracts, diff --git a/modules/gapi/include/opencv2/gapi/util/util.hpp b/modules/gapi/include/opencv2/gapi/util/util.hpp index afcf5596fd60..c6ad0632e268 100644 --- a/modules/gapi/include/opencv2/gapi/util/util.hpp +++ b/modules/gapi/include/opencv2/gapi/util/util.hpp @@ -117,6 +117,43 @@ namespace detail static type get(std::tuple&& objs) { return std::forward>(objs); } }; } // namespace detail + +namespace util +{ +template +struct overload_lamba_set; + +template +struct overload_lamba_set : public L1 +{ + overload_lamba_set(L1&& lambda) : L1(std::move(lambda)) {} + overload_lamba_set(const L1& lambda) : L1(lambda) {} + + using L1::operator(); +}; + +template +struct overload_lamba_set : public L1, public overload_lamba_set +{ + using base_type = overload_lamba_set; + overload_lamba_set(L1 &&lambda1, L&& ...lambdas): + L1(std::move(lambda1)), + base_type(std::forward(lambdas)...) {} + + overload_lamba_set(const L1 &lambda1, L&& ...lambdas): + L1(lambda1), + base_type(std::forward(lambdas)...) {} + + using L1::operator(); + using base_type::operator(); +}; + +template +overload_lamba_set overload_lambdas(L&& ...lambdas) +{ + return overload_lamba_set(std::forward(lambdas)...); +} +} } // namespace cv // \endcond diff --git a/modules/gapi/include/opencv2/gapi/util/variant.hpp b/modules/gapi/include/opencv2/gapi/util/variant.hpp index 71a06d2dcf22..f412110deb76 100644 --- a/modules/gapi/include/opencv2/gapi/util/variant.hpp +++ b/modules/gapi/include/opencv2/gapi/util/variant.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include // max_of_t #include @@ -44,6 +45,12 @@ namespace util static const constexpr std::size_t value = detail::type_list_index_helper<0, Target, Types...>::value; }; + template + struct type_list_element + { + using type = typename std::tuple_element >::type; + }; + class bad_variant_access: public std::exception { public: @@ -233,9 +240,87 @@ namespace util template const T& get(const util::variant &v); + template + typename util::type_list_element::type& get(util::variant &v); + + template + const typename util::type_list_element::type& get(const util::variant &v); + template bool holds_alternative(const util::variant &v) noexcept; + + // Visitor + namespace detail + { + struct visitor_interface {}; + + // Class `visitor_return_type_deduction_helper` + // introduces solution for deduction `return_type` in `visit` function in common way + // for both Lambda and class Visitor and keep one interface invocation point: `visit` only + // his helper class is required to unify return_type deduction mechanism because + // for Lambda it is possible to take type of `decltype(visitor(get<0>(var)))` + // but for class Visitor there is no operator() in base case, + // because it provides `operator() (std::size_t index, ...)` + // So `visitor_return_type_deduction_helper` expose `operator()` + // uses only for class Visitor only for deduction `return type` in visit() + template + struct visitor_return_type_deduction_helper + { + using return_type = R; + + // to be used in Lambda return type deduction context only + template + return_type operator() (T&&); + }; + } + + // Special purpose `static_visitor` can receive additional arguments + template + struct static_visitor : public detail::visitor_interface, + public detail::visitor_return_type_deduction_helper { + + // assign responsibility for return type deduction to helper class + using return_type = typename detail::visitor_return_type_deduction_helper::return_type; + using detail::visitor_return_type_deduction_helper::operator(); + friend Impl; + + template + return_type operator() (std::size_t index, VariantValue&& value, Args&& ...args) + { + suppress_unused_warning(index); + return static_cast(this)-> visit( + std::forward(value), + std::forward(args)...); + } + }; + + // Special purpose `static_indexed_visitor` can receive additional arguments + // And make forwarding current variant index as runtime function argument to its `Impl` + template + struct static_indexed_visitor : public detail::visitor_interface, + public detail::visitor_return_type_deduction_helper { + + // assign responsibility for return type deduction to helper class + using return_type = typename detail::visitor_return_type_deduction_helper::return_type; + using detail::visitor_return_type_deduction_helper::operator(); + friend Impl; + + template + return_type operator() (std::size_t Index, VariantValue&& value, Args&& ...args) + { + return static_cast(this)-> visit(Index, + std::forward(value), + std::forward(args)...); + } + }; + + template + struct variant_size; + + template + struct variant_size> + : std::integral_constant { }; // FIXME: T&&, const TT&& versions. // Implementation ////////////////////////////////////////////////////////// @@ -402,6 +487,22 @@ namespace util throw_error(bad_variant_access()); } + template + typename util::type_list_element::type& get(util::variant &v) + { + using ReturnType = typename util::type_list_element::type; + return const_cast(get(static_cast &>(v))); + } + + template + const typename util::type_list_element::type& get(const util::variant &v) + { + static_assert(Index < sizeof...(Types), + "`Index` it out of bound of `util::variant` type list"); + using ReturnType = typename util::type_list_element::type; + return get(v); + } + template bool holds_alternative(const util::variant &v) noexcept { @@ -428,7 +529,130 @@ namespace util { return !(lhs == rhs); } -} // namespace cv + +namespace detail +{ + // terminate recursion implementation for `non-void` ReturnType + template + ReturnType apply_visitor_impl(Visitor&&, Variant&, + std::true_type, std::false_type, + VisitorArgs&& ...) + { + return {}; + } + + // terminate recursion implementation for `void` ReturnType + template + void apply_visitor_impl(Visitor&&, Variant&, + std::true_type, std::true_type, + VisitorArgs&& ...) + { + } + + // Intermediate resursion processor for Lambda Visitors + template + typename std::enable_if::type>::value, ReturnType>::type + apply_visitor_impl(Visitor&& visitor, Variant&& v, std::false_type not_processed, + std::integral_constant should_no_return, + VisitorArgs&& ...args) + { + static_assert(std::is_same(v)))>::value, + "Different `ReturnType`s detected! All `Visitor::visit` or `overload_lamba_set`" + " must return the same type"); + suppress_unused_warning(not_processed); + if (v.index() == CurIndex) + { + return visitor.operator()(get(v), std::forward(args)... ); + } + + using is_variant_processed_t = std::integral_constant= ElemCount>; + return apply_visitor_impl( + std::forward(visitor), + std::forward(v), + is_variant_processed_t{}, + should_no_return, + std::forward(args)...); + } + + //Visual Studio 2014 compilation fix: cast visitor to base class before invoke operator() + template + typename std::enable_if::type>, + typename std::decay::type>::value, ReturnType>::type + invoke_class_visitor(Visitor& visitor, Value&& v, VisitorArgs&&...args) + { + return static_cast::type>&>(visitor).operator() (CurIndex, std::forward(v), std::forward(args)... ); + } + + //Visual Studio 2014 compilation fix: cast visitor to base class before invoke operator() + template + typename std::enable_if::type>, + typename std::decay::type>::value, ReturnType>::type + invoke_class_visitor(Visitor& visitor, Value&& v, VisitorArgs&&...args) + { + return static_cast::type>&>(visitor).operator() (CurIndex, std::forward(v), std::forward(args)... ); + } + + // Intermediate recursion processor for special case `visitor_interface` derived Visitors + template + typename std::enable_if::type>::value, ReturnType>::type + apply_visitor_impl(Visitor&& visitor, Variant&& v, std::false_type not_processed, + std::integral_constant should_no_return, + VisitorArgs&& ...args) + { + static_assert(std::is_same(v)))>::value, + "Different `ReturnType`s detected! All `Visitor::visit` or `overload_lamba_set`" + " must return the same type"); + suppress_unused_warning(not_processed); + if (v.index() == CurIndex) + { + return invoke_class_visitor(visitor, get(v), std::forward(args)... ); + } + + using is_variant_processed_t = std::integral_constant= ElemCount>; + return apply_visitor_impl( + std::forward(visitor), + std::forward(v), + is_variant_processed_t{}, + should_no_return, + std::forward(args)...); + } +} // namespace detail + + template + auto visit(Visitor &visitor, const Variant& var, VisitorArg &&...args) -> decltype(visitor(get<0>(var))) + { + constexpr std::size_t varsize = util::variant_size::value; + static_assert(varsize != 0, "utils::variant must contains one type at least "); + using is_variant_processed_t = std::false_type; + + using ReturnType = decltype(visitor(get<0>(var))); + using return_t = std::is_same; + return detail::apply_visitor_impl( + std::forward(visitor), + var, is_variant_processed_t{}, + return_t{}, + std::forward(args)...); + } + + template + auto visit(Visitor&& visitor, const Variant& var) -> decltype(visitor(get<0>(var))) + { + constexpr std::size_t varsize = util::variant_size::value; + static_assert(varsize != 0, "utils::variant must contains one type at least "); + using is_variant_processed_t = std::false_type; + + using ReturnType = decltype(visitor(get<0>(var))); + using return_t = std::is_same; + return detail::apply_visitor_impl( + std::forward(visitor), + var, is_variant_processed_t{}, + return_t{}); + } } // namespace util +} // namespace cv #endif // OPENCV_GAPI_UTIL_VARIANT_HPP diff --git a/modules/gapi/include/opencv2/gapi/video.hpp b/modules/gapi/include/opencv2/gapi/video.hpp index 10965b0aa65f..4dcc1d418241 100644 --- a/modules/gapi/include/opencv2/gapi/video.hpp +++ b/modules/gapi/include/opencv2/gapi/video.hpp @@ -42,6 +42,10 @@ struct GAPI_EXPORTS KalmanParams Mat controlMatrix; }; +/** + * @brief This namespace contains G-API Operations and functions for + * video-oriented algorithms, like optical flow and background subtraction. + */ namespace video { using GBuildPyrOutput = std::tuple, GScalar>; diff --git a/modules/gapi/misc/python/package/gapi/__init__.py b/modules/gapi/misc/python/package/gapi/__init__.py index 733c980010af..dc874f0b0ca5 100644 --- a/modules/gapi/misc/python/package/gapi/__init__.py +++ b/modules/gapi/misc/python/package/gapi/__init__.py @@ -11,6 +11,36 @@ def parameterized(func): return parameterized +@register('cv2.gapi') +def networks(*args): + return cv.gapi_GNetPackage(list(map(cv.detail.strip, args))) + + +@register('cv2.gapi') +def compile_args(*args): + return list(map(cv.GCompileArg, args)) + + +@register('cv2') +def GIn(*args): + return [*args] + + +@register('cv2') +def GOut(*args): + return [*args] + + +@register('cv2') +def gin(*args): + return [*args] + + +@register('cv2.gapi') +def descr_of(*args): + return [*args] + + @register('cv2') class GOpaque(): # NB: Inheritance from c++ class cause segfault. @@ -54,6 +84,10 @@ class Rect(): def __new__(self): return cv.GOpaqueT(cv.gapi.CV_RECT) + class Prim(): + def __new__(self): + return cv.GOpaqueT(cv.gapi.CV_DRAW_PRIM) + class Any(): def __new__(self): return cv.GOpaqueT(cv.gapi.CV_ANY) @@ -113,6 +147,10 @@ class GMat(): def __new__(self): return cv.GArrayT(cv.gapi.CV_GMAT) + class Prim(): + def __new__(self): + return cv.GArray(cv.gapi.CV_DRAW_PRIM) + class Any(): def __new__(self): return cv.GArray(cv.gapi.CV_ANY) @@ -134,6 +172,7 @@ def op(op_id, in_types, out_types): cv.GArray.Scalar: cv.gapi.CV_SCALAR, cv.GArray.Mat: cv.gapi.CV_MAT, cv.GArray.GMat: cv.gapi.CV_GMAT, + cv.GArray.Prim: cv.gapi.CV_DRAW_PRIM, cv.GArray.Any: cv.gapi.CV_ANY } @@ -149,22 +188,24 @@ def op(op_id, in_types, out_types): cv.GOpaque.Point2f: cv.gapi.CV_POINT2F, cv.GOpaque.Size: cv.gapi.CV_SIZE, cv.GOpaque.Rect: cv.gapi.CV_RECT, + cv.GOpaque.Prim: cv.gapi.CV_DRAW_PRIM, cv.GOpaque.Any: cv.gapi.CV_ANY } type2str = { - cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' , - cv.gapi.CV_INT: 'cv.gapi.CV_INT' , - cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' , - cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' , - cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' , - cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' , - cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' , - cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE', - cv.gapi.CV_RECT: 'cv.gapi.CV_RECT', - cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR', - cv.gapi.CV_MAT: 'cv.gapi.CV_MAT', - cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT' + cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' , + cv.gapi.CV_INT: 'cv.gapi.CV_INT' , + cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' , + cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' , + cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' , + cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' , + cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' , + cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE', + cv.gapi.CV_RECT: 'cv.gapi.CV_RECT', + cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR', + cv.gapi.CV_MAT: 'cv.gapi.CV_MAT', + cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT', + cv.gapi.CV_DRAW_PRIM: 'cv.gapi.CV_DRAW_PRIM' } # NB: Second lvl decorator takes class to decorate @@ -244,3 +285,13 @@ def kernel_with_params(cls): return cls return kernel_with_params + + +# FIXME: On the c++ side every class is placed in cv2 module. +cv.gapi.wip.draw.Rect = cv.gapi_wip_draw_Rect +cv.gapi.wip.draw.Text = cv.gapi_wip_draw_Text +cv.gapi.wip.draw.Circle = cv.gapi_wip_draw_Circle +cv.gapi.wip.draw.Line = cv.gapi_wip_draw_Line +cv.gapi.wip.draw.Mosaic = cv.gapi_wip_draw_Mosaic +cv.gapi.wip.draw.Image = cv.gapi_wip_draw_Image +cv.gapi.wip.draw.Poly = cv.gapi_wip_draw_Poly diff --git a/modules/gapi/misc/python/pyopencv_gapi.hpp b/modules/gapi/misc/python/pyopencv_gapi.hpp index 3ade7aaa4e14..d378a91b5fd6 100644 --- a/modules/gapi/misc/python/pyopencv_gapi.hpp +++ b/modules/gapi/misc/python/pyopencv_gapi.hpp @@ -17,6 +17,7 @@ using gapi_ie_PyParams = cv::gapi::ie::PyParams; using gapi_wip_IStreamSource_Ptr = cv::Ptr; using detail_ExtractArgsCallback = cv::detail::ExtractArgsCallback; using detail_ExtractMetaCallback = cv::detail::ExtractMetaCallback; +using vector_GNetParam = std::vector; // NB: Python wrapper generate T_U for T // This behavior is only observed for inputs @@ -42,6 +43,7 @@ using GArray_Rect = cv::GArray; using GArray_Scalar = cv::GArray; using GArray_Mat = cv::GArray; using GArray_GMat = cv::GArray; +using GArray_Prim = cv::GArray; // FIXME: Python wrapper generate code without namespace std, // so it cause error: "string wasn't declared" @@ -124,6 +126,66 @@ PyObject* pyopencv_from(const cv::detail::PyObjectHolder& v) return o; } +// #FIXME: Is it possible to implement pyopencv_from/pyopencv_to for generic +// cv::variant ? +template <> +PyObject* pyopencv_from(const cv::gapi::wip::draw::Prim& prim) +{ + switch (prim.index()) + { + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + case cv::gapi::wip::draw::Prim::index_of(): + return pyopencv_from(cv::util::get(prim)); + } + + util::throw_error(std::logic_error("Unsupported draw primitive type")); +} + +template <> +PyObject* pyopencv_from(const cv::gapi::wip::draw::Prims& value) +{ + return pyopencv_from_generic_vec(value); +} + +template<> +bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo& info) +{ +#define TRY_EXTRACT(Prim) \ + if (PyObject_TypeCheck(obj, reinterpret_cast(pyopencv_gapi_wip_draw_##Prim##_TypePtr))) \ + { \ + value = reinterpret_cast(obj)->v; \ + return true; \ + } \ + + TRY_EXTRACT(Rect) + TRY_EXTRACT(Text) + TRY_EXTRACT(Circle) + TRY_EXTRACT(Line) + TRY_EXTRACT(Mosaic) + TRY_EXTRACT(Image) + TRY_EXTRACT(Poly) + + failmsg("Unsupported primitive type"); + return false; +} + +template <> +bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prims& value, const ArgInfo& info) +{ + return pyopencv_to_generic_vec(obj, value, info); +} + template<> PyObject* pyopencv_from(const cv::GArg& value) { @@ -136,20 +198,21 @@ PyObject* pyopencv_from(const cv::GArg& value) #define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break switch (value.opaque_kind) { - HANDLE_CASE(BOOL, bool); - HANDLE_CASE(INT, int); - HANDLE_CASE(DOUBLE, double); - HANDLE_CASE(FLOAT, float); - HANDLE_CASE(STRING, std::string); - HANDLE_CASE(POINT, cv::Point); - HANDLE_CASE(POINT2F, cv::Point2f); - HANDLE_CASE(SIZE, cv::Size); - HANDLE_CASE(RECT, cv::Rect); - HANDLE_CASE(SCALAR, cv::Scalar); - HANDLE_CASE(MAT, cv::Mat); - HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder); + HANDLE_CASE(BOOL, bool); + HANDLE_CASE(INT, int); + HANDLE_CASE(INT64, int64_t); + HANDLE_CASE(DOUBLE, double); + HANDLE_CASE(FLOAT, float); + HANDLE_CASE(STRING, std::string); + HANDLE_CASE(POINT, cv::Point); + HANDLE_CASE(POINT2F, cv::Point2f); + HANDLE_CASE(SIZE, cv::Size); + HANDLE_CASE(RECT, cv::Rect); + HANDLE_CASE(SCALAR, cv::Scalar); + HANDLE_CASE(MAT, cv::Mat); + HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder); + HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim); UNSUPPORTED(UINT64); - UNSUPPORTED(DRAW_PRIM); #undef HANDLE_CASE #undef UNSUPPORTED } @@ -164,23 +227,29 @@ bool pyopencv_to(PyObject* obj, cv::GArg& value, const ArgInfo& info) } template <> -bool pyopencv_to(PyObject* obj, std::vector& value, const ArgInfo& info) +bool pyopencv_to(PyObject* obj, std::vector& value, const ArgInfo& info) { return pyopencv_to_generic_vec(obj, value, info); } template <> -PyObject* pyopencv_from(const std::vector& value) +PyObject* pyopencv_from(const std::vector& value) { return pyopencv_from_generic_vec(value); } template <> -bool pyopencv_to(PyObject* obj, GRunArgs& value, const ArgInfo& info) +bool pyopencv_to(PyObject* obj, std::vector& value, const ArgInfo& info) { return pyopencv_to_generic_vec(obj, value, info); } +template <> +PyObject* pyopencv_from(const std::vector& value) +{ + return pyopencv_from_generic_vec(value); +} + template<> PyObject* pyopencv_from(const cv::detail::OpaqueRef& o) { @@ -188,6 +257,7 @@ PyObject* pyopencv_from(const cv::detail::OpaqueRef& o) { case cv::detail::OpaqueKind::CV_BOOL : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_INT : return pyopencv_from(o.rref()); + case cv::detail::OpaqueKind::CV_INT64 : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_DOUBLE : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_FLOAT : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from(o.rref()); @@ -196,10 +266,10 @@ PyObject* pyopencv_from(const cv::detail::OpaqueRef& o) case cv::detail::OpaqueKind::CV_SIZE : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_RECT : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_UNKNOWN : return pyopencv_from(o.rref()); + case cv::detail::OpaqueKind::CV_DRAW_PRIM : return pyopencv_from(o.rref()); case cv::detail::OpaqueKind::CV_UINT64 : break; case cv::detail::OpaqueKind::CV_SCALAR : break; case cv::detail::OpaqueKind::CV_MAT : break; - case cv::detail::OpaqueKind::CV_DRAW_PRIM : break; } PyErr_SetString(PyExc_TypeError, "Unsupported GOpaque type"); @@ -213,6 +283,7 @@ PyObject* pyopencv_from(const cv::detail::VectorRef& v) { case cv::detail::OpaqueKind::CV_BOOL : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_INT : return pyopencv_from_generic_vec(v.rref()); + case cv::detail::OpaqueKind::CV_INT64 : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_DOUBLE : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_FLOAT : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from_generic_vec(v.rref()); @@ -223,8 +294,8 @@ PyObject* pyopencv_from(const cv::detail::VectorRef& v) case cv::detail::OpaqueKind::CV_SCALAR : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_MAT : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_UNKNOWN : return pyopencv_from_generic_vec(v.rref()); + case cv::detail::OpaqueKind::CV_DRAW_PRIM : return pyopencv_from_generic_vec(v.rref()); case cv::detail::OpaqueKind::CV_UINT64 : break; - case cv::detail::OpaqueKind::CV_DRAW_PRIM : break; } PyErr_SetString(PyExc_TypeError, "Unsupported GArray type"); @@ -249,52 +320,69 @@ PyObject* pyopencv_from(const GRunArg& v) return pyopencv_from(util::get(v)); } - PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs"); + PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs. Index of variant is unknown"); return NULL; } -template<> -PyObject* pyopencv_from(const GRunArgs& value) +template +PyObject* pyopencv_from(const cv::optional& opt) { - size_t i, n = value.size(); - - // NB: It doesn't make sense to return list with a single element - if (n == 1) + if (!opt.has_value()) { - PyObject* item = pyopencv_from(value[0]); - if(!item) - { - return NULL; - } - return item; + Py_RETURN_NONE; } + return pyopencv_from(*opt); +} - PyObject* list = PyList_New(n); - for(i = 0; i < n; ++i) +template <> +PyObject* pyopencv_from(const GOptRunArg& v) +{ + switch (v.index()) { - PyObject* item = pyopencv_from(value[i]); - if(!item) - { - Py_DECREF(list); - PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs"); - return NULL; - } - PyList_SetItem(list, i, item); + case GOptRunArg::index_of>(): + return pyopencv_from(util::get>(v)); + + case GOptRunArg::index_of>(): + return pyopencv_from(util::get>(v)); + + case GOptRunArg::index_of>(): + return pyopencv_from(util::get>(v)); + + case GOptRunArg::index_of>(): + return pyopencv_from(util::get>(v)); } - return list; + PyErr_SetString(PyExc_TypeError, "Failed to unpack GOptRunArg. Index of variant is unknown"); + return NULL; } template<> -bool pyopencv_to(PyObject* obj, GMetaArgs& value, const ArgInfo& info) +PyObject* pyopencv_from(const GRunArgs& value) { - return pyopencv_to_generic_vec(obj, value, info); + return value.size() == 1 ? pyopencv_from(value[0]) : pyopencv_from_generic_vec(value); } template<> -PyObject* pyopencv_from(const GMetaArgs& value) +PyObject* pyopencv_from(const GOptRunArgs& value) { - return pyopencv_from_generic_vec(value); + return value.size() == 1 ? pyopencv_from(value[0]) : pyopencv_from_generic_vec(value); +} + +// FIXME: cv::variant should be wrapped once for all types. +template <> +PyObject* pyopencv_from(const cv::util::variant& v) +{ + using RunArgs = cv::util::variant; + switch (v.index()) + { + case RunArgs::index_of(): + return pyopencv_from(util::get(v)); + case RunArgs::index_of(): + return pyopencv_from(util::get(v)); + } + + PyErr_SetString(PyExc_TypeError, "Failed to recognize kind of RunArgs. Index of variant is unknown"); + return NULL; } template @@ -318,16 +406,16 @@ void pyopencv_to_generic_vec_with_check(PyObject* from, } template -static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw) +static T extract_proto_args(PyObject* py_args) { using namespace cv; GProtoArgs args; - Py_ssize_t size = PyTuple_Size(py_args); + Py_ssize_t size = PyList_Size(py_args); args.reserve(size); for (int i = 0; i < size; ++i) { - PyObject* item = PyTuple_GetItem(py_args, i); + PyObject* item = PyList_GetItem(py_args, i); if (PyObject_TypeCheck(item, reinterpret_cast(pyopencv_GScalar_TypePtr))) { args.emplace_back(reinterpret_cast(item)->v); @@ -346,22 +434,11 @@ static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw) } else { - PyErr_SetString(PyExc_TypeError, "Unsupported type for cv.GIn()/cv.GOut()"); - return NULL; + util::throw_error(std::logic_error("Unsupported type for GProtoArgs")); } } - return pyopencv_from(T{std::move(args)}); -} - -static PyObject* pyopencv_cv_GIn(PyObject* , PyObject* py_args, PyObject* kw) -{ - return extract_proto_args(py_args, kw); -} - -static PyObject* pyopencv_cv_GOut(PyObject* , PyObject* py_args, PyObject* kw) -{ - return extract_proto_args(py_args, kw); + return T(std::move(args)); } static cv::detail::OpaqueRef extract_opaque_ref(PyObject* from, cv::detail::OpaqueKind kind) @@ -386,6 +463,7 @@ static cv::detail::OpaqueRef extract_opaque_ref(PyObject* from, cv::detail::Opaq HANDLE_CASE(RECT, cv::Rect); HANDLE_CASE(UNKNOWN, cv::GArg); UNSUPPORTED(UINT64); + UNSUPPORTED(INT64); UNSUPPORTED(SCALAR); UNSUPPORTED(MAT); UNSUPPORTED(DRAW_PRIM); @@ -406,20 +484,21 @@ static cv::detail::VectorRef extract_vector_ref(PyObject* from, cv::detail::Opaq #define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break switch (kind) { - HANDLE_CASE(BOOL, bool); - HANDLE_CASE(INT, int); - HANDLE_CASE(DOUBLE, double); - HANDLE_CASE(FLOAT, float); - HANDLE_CASE(STRING, std::string); - HANDLE_CASE(POINT, cv::Point); - HANDLE_CASE(POINT2F, cv::Point2f); - HANDLE_CASE(SIZE, cv::Size); - HANDLE_CASE(RECT, cv::Rect); - HANDLE_CASE(SCALAR, cv::Scalar); - HANDLE_CASE(MAT, cv::Mat); - HANDLE_CASE(UNKNOWN, cv::GArg); + HANDLE_CASE(BOOL, bool); + HANDLE_CASE(INT, int); + HANDLE_CASE(DOUBLE, double); + HANDLE_CASE(FLOAT, float); + HANDLE_CASE(STRING, std::string); + HANDLE_CASE(POINT, cv::Point); + HANDLE_CASE(POINT2F, cv::Point2f); + HANDLE_CASE(SIZE, cv::Size); + HANDLE_CASE(RECT, cv::Rect); + HANDLE_CASE(SCALAR, cv::Scalar); + HANDLE_CASE(MAT, cv::Mat); + HANDLE_CASE(UNKNOWN, cv::GArg); + HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim); UNSUPPORTED(UINT64); - UNSUPPORTED(DRAW_PRIM); + UNSUPPORTED(INT64); #undef HANDLE_CASE #undef UNSUPPORTED } @@ -470,13 +549,15 @@ static cv::GRunArg extract_run_arg(const cv::GTypeInfo& info, PyObject* item) static cv::GRunArgs extract_run_args(const cv::GTypesInfo& info, PyObject* py_args) { + GAPI_Assert(PyList_Check(py_args)); + cv::GRunArgs args; - Py_ssize_t tuple_size = PyTuple_Size(py_args); - args.reserve(tuple_size); + Py_ssize_t list_size = PyList_Size(py_args); + args.reserve(list_size); - for (int i = 0; i < tuple_size; ++i) + for (int i = 0; i < list_size; ++i) { - args.push_back(extract_run_arg(info[i], PyTuple_GetItem(py_args, i))); + args.push_back(extract_run_arg(info[i], PyList_GetItem(py_args, i))); } return args; @@ -517,13 +598,15 @@ static cv::GMetaArg extract_meta_arg(const cv::GTypeInfo& info, PyObject* item) static cv::GMetaArgs extract_meta_args(const cv::GTypesInfo& info, PyObject* py_args) { + GAPI_Assert(PyList_Check(py_args)); + cv::GMetaArgs metas; - Py_ssize_t tuple_size = PyTuple_Size(py_args); - metas.reserve(tuple_size); + Py_ssize_t list_size = PyList_Size(py_args); + metas.reserve(list_size); - for (int i = 0; i < tuple_size; ++i) + for (int i = 0; i < list_size; ++i) { - metas.push_back(extract_meta_arg(info[i], PyTuple_GetItem(py_args, i))); + metas.push_back(extract_meta_arg(info[i], PyList_GetItem(py_args, i))); } return metas; @@ -581,7 +664,8 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel, cv::detail::PyObjectHolder result( PyObject_CallObject(kernel.get(), args.get()), false); - if (PyErr_Occurred()) { + if (PyErr_Occurred()) + { PyErr_PrintEx(0); PyErr_Clear(); throw std::logic_error("Python kernel failed with error!"); @@ -589,8 +673,27 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel, // NB: In fact it's impossible situation, becase errors were handled above. GAPI_Assert(result.get() && "Python kernel returned NULL!"); - outs = out_info.size() == 1 ? cv::GRunArgs{extract_run_arg(out_info[0], result.get())} - : extract_run_args(out_info, result.get()); + if (out_info.size() == 1) + { + outs = cv::GRunArgs{extract_run_arg(out_info[0], result.get())}; + } + else if (out_info.size() > 1) + { + GAPI_Assert(PyTuple_Check(result.get())); + + Py_ssize_t tuple_size = PyTuple_Size(result.get()); + outs.reserve(tuple_size); + + for (int i = 0; i < tuple_size; ++i) + { + outs.push_back(extract_run_arg(out_info[i], PyTuple_GetItem(result.get(), i))); + } + } + else + { + // Seems to be impossible case. + GAPI_Assert(false); + } } catch (...) { @@ -645,8 +748,9 @@ static cv::GMetaArgs get_meta_args(PyObject* tuple) } static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta, - const cv::GMetaArgs &meta, - const cv::GArgs &gargs) { + const cv::GMetaArgs &meta, + const cv::GArgs &gargs) +{ PyGILState_STATE gstate; gstate = PyGILState_Ensure(); @@ -688,7 +792,8 @@ static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta, cv::detail::PyObjectHolder result( PyObject_CallObject(out_meta.get(), args.get()), false); - if (PyErr_Occurred()) { + if (PyErr_Occurred()) + { PyErr_PrintEx(0); PyErr_Clear(); throw std::logic_error("Python outMeta failed with error!"); @@ -720,21 +825,24 @@ static PyObject* pyopencv_cv_gapi_kernels(PyObject* , PyObject* py_args, PyObjec PyObject* user_kernel = PyTuple_GetItem(py_args, i); PyObject* id_obj = PyObject_GetAttrString(user_kernel, "id"); - if (!id_obj) { + if (!id_obj) + { PyErr_SetString(PyExc_TypeError, "Python kernel should contain id, please use cv.gapi.kernel to define kernel"); return NULL; } PyObject* out_meta = PyObject_GetAttrString(user_kernel, "outMeta"); - if (!out_meta) { + if (!out_meta) + { PyErr_SetString(PyExc_TypeError, "Python kernel should contain outMeta, please use cv.gapi.kernel to define kernel"); return NULL; } PyObject* run = PyObject_GetAttrString(user_kernel, "run"); - if (!run) { + if (!run) + { PyErr_SetString(PyExc_TypeError, "Python kernel should contain run, please use cv.gapi.kernel to define kernel"); return NULL; @@ -817,53 +925,54 @@ static PyObject* pyopencv_cv_gapi_op(PyObject* , PyObject* py_args, PyObject*) return pyopencv_from(cv::gapi::wip::op(id, outMetaWrapper, std::move(args))); } -static PyObject* pyopencv_cv_gin(PyObject*, PyObject* py_args, PyObject*) +template<> +bool pyopencv_to(PyObject* obj, cv::detail::ExtractArgsCallback& value, const ArgInfo&) { - cv::detail::PyObjectHolder holder{py_args}; - auto callback = cv::detail::ExtractArgsCallback{[=](const cv::GTypesInfo& info) - { - PyGILState_STATE gstate; - gstate = PyGILState_Ensure(); + cv::detail::PyObjectHolder holder{obj}; + value = cv::detail::ExtractArgsCallback{[=](const cv::GTypesInfo& info) + { + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); - cv::GRunArgs args; - try - { - args = extract_run_args(info, holder.get()); - } - catch (...) - { - PyGILState_Release(gstate); - throw; - } + cv::GRunArgs args; + try + { + args = extract_run_args(info, holder.get()); + } + catch (...) + { PyGILState_Release(gstate); - return args; - }}; - - return pyopencv_from(callback); + throw; + } + PyGILState_Release(gstate); + return args; + }}; + return true; } -static PyObject* pyopencv_cv_descr_of(PyObject*, PyObject* py_args, PyObject*) +template<> +bool pyopencv_to(PyObject* obj, cv::detail::ExtractMetaCallback& value, const ArgInfo&) { - Py_INCREF(py_args); - auto callback = cv::detail::ExtractMetaCallback{[=](const cv::GTypesInfo& info) - { - PyGILState_STATE gstate; - gstate = PyGILState_Ensure(); + cv::detail::PyObjectHolder holder{obj}; + value = cv::detail::ExtractMetaCallback{[=](const cv::GTypesInfo& info) + { + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); - cv::GMetaArgs args; - try - { - args = extract_meta_args(info, py_args); - } - catch (...) - { - PyGILState_Release(gstate); - throw; - } + cv::GMetaArgs args; + try + { + args = extract_meta_args(info, holder.get()); + } + catch (...) + { PyGILState_Release(gstate); - return args; - }}; - return pyopencv_from(callback); + throw; + } + PyGILState_Release(gstate); + return args; + }}; + return true; } template @@ -878,9 +987,12 @@ struct PyOpenCV_Converter> if (PyObject_TypeCheck(obj, reinterpret_cast(pyopencv_GArrayT_TypePtr))) { auto& array = reinterpret_cast(obj)->v; - try { + try + { value = cv::util::get>(array.arg()); - } catch (...) { + } + catch (...) + { return false; } return true; @@ -901,9 +1013,12 @@ struct PyOpenCV_Converter> if (PyObject_TypeCheck(obj, reinterpret_cast(pyopencv_GOpaqueT_TypePtr))) { auto& opaque = reinterpret_cast(obj)->v; - try { + try + { value = cv::util::get>(opaque.arg()); - } catch (...) { + } + catch (...) + { return false; } return true; @@ -912,6 +1027,35 @@ struct PyOpenCV_Converter> } }; +template<> +bool pyopencv_to(PyObject* obj, cv::GProtoInputArgs& value, const ArgInfo& info) +{ + try + { + value = extract_proto_args(obj); + return true; + } + catch (...) + { + failmsg("Can't parse cv::GProtoInputArgs"); + return false; + } +} + +template<> +bool pyopencv_to(PyObject* obj, cv::GProtoOutputArgs& value, const ArgInfo& info) +{ + try + { + value = extract_proto_args(obj); + return true; + } + catch (...) + { + failmsg("Can't parse cv::GProtoOutputArgs"); + return false; + } +} // extend cv.gapi methods #define PYOPENCV_EXTRA_METHODS_GAPI \ diff --git a/modules/gapi/misc/python/python_bridge.hpp b/modules/gapi/misc/python/python_bridge.hpp index 0d1c6d51c574..11d17287308e 100644 --- a/modules/gapi/misc/python/python_bridge.hpp +++ b/modules/gapi/misc/python/python_bridge.hpp @@ -10,6 +10,7 @@ #include #include #include +#include // Prim #define ID(T, E) T #define ID_(T, E) ID(T, E), @@ -24,24 +25,29 @@ GAPI_Assert(false && "Unsupported type"); \ } +using cv::gapi::wip::draw::Prim; + #define GARRAY_TYPE_LIST_G(G, G2) \ -WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \ -WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \ -WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \ -WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \ -WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \ -WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \ -WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \ -WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \ -WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \ -WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \ -WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, G) \ -WRAP_ARGS(cv::GArg , cv::gapi::ArgType::CV_ANY, G) \ -WRAP_ARGS(cv::GMat , cv::gapi::ArgType::CV_GMAT, G2) \ +WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \ +WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \ +WRAP_ARGS(int64_t , cv::gapi::ArgType::CV_INT64, G) \ +WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \ +WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \ +WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \ +WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \ +WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \ +WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \ +WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \ +WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \ +WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, G) \ +WRAP_ARGS(Prim , cv::gapi::ArgType::CV_DRAW_PRIM, G) \ +WRAP_ARGS(cv::GArg , cv::gapi::ArgType::CV_ANY, G) \ +WRAP_ARGS(cv::GMat , cv::gapi::ArgType::CV_GMAT, G2) \ #define GOPAQUE_TYPE_LIST_G(G, G2) \ WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \ WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \ +WRAP_ARGS(int64_t , cv::gapi::ArgType::CV_INT64, G) \ WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \ WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \ WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \ @@ -58,6 +64,7 @@ namespace gapi { enum ArgType { CV_BOOL, CV_INT, + CV_INT64, CV_DOUBLE, CV_FLOAT, CV_STRING, @@ -68,6 +75,7 @@ enum ArgType { CV_SCALAR, CV_MAT, CV_GMAT, + CV_DRAW_PRIM, CV_ANY, }; diff --git a/modules/gapi/misc/python/samples/gaze_estimation.py b/modules/gapi/misc/python/samples/gaze_estimation.py new file mode 100644 index 000000000000..db190f67bb99 --- /dev/null +++ b/modules/gapi/misc/python/samples/gaze_estimation.py @@ -0,0 +1,467 @@ +import argparse +import time +import numpy as np +import cv2 as cv + +# ------------------------Service operations------------------------ +def weight_path(model_path): + """ Get path of weights based on path to IR + + Params: + model_path: the string contains path to IR file + + Return: + Path to weights file + """ + assert model_path.endswith('.xml'), "Wrong topology path was provided" + return model_path[:-3] + 'bin' + + +def build_argparser(): + """ Parse arguments from command line + + Return: + Pack of arguments from command line + """ + parser = argparse.ArgumentParser(description='This is an OpenCV-based version of Gaze Estimation example') + + parser.add_argument('--input', + help='Path to the input video file') + parser.add_argument('--out', + help='Path to the output video file') + parser.add_argument('--facem', + default='face-detection-retail-0005.xml', + help='Path to OpenVINO face detection model (.xml)') + parser.add_argument('--faced', + default='CPU', + help='Target device for the face detection' + + '(e.g. CPU, GPU, VPU, ...)') + parser.add_argument('--headm', + default='head-pose-estimation-adas-0001.xml', + help='Path to OpenVINO head pose estimation model (.xml)') + parser.add_argument('--headd', + default='CPU', + help='Target device for the head pose estimation inference ' + + '(e.g. CPU, GPU, VPU, ...)') + parser.add_argument('--landm', + default='facial-landmarks-35-adas-0002.xml', + help='Path to OpenVINO landmarks detector model (.xml)') + parser.add_argument('--landd', + default='CPU', + help='Target device for the landmarks detector (e.g. CPU, GPU, VPU, ...)') + parser.add_argument('--gazem', + default='gaze-estimation-adas-0002.xml', + help='Path to OpenVINO gaze vector estimaiton model (.xml)') + parser.add_argument('--gazed', + default='CPU', + help='Target device for the gaze vector estimation inference ' + + '(e.g. CPU, GPU, VPU, ...)') + parser.add_argument('--eyem', + default='open-closed-eye-0001.xml', + help='Path to OpenVINO open closed eye model (.xml)') + parser.add_argument('--eyed', + default='CPU', + help='Target device for the eyes state inference (e.g. CPU, GPU, VPU, ...)') + return parser + + +# ------------------------Support functions for custom kernels------------------------ +def intersection(surface, rect): + """ Remove zone of out of bound from ROI + + Params: + surface: image bounds is rect representation (top left coordinates and width and height) + rect: region of interest is also has rect representation + + Return: + Modified ROI with correct bounds + """ + l_x = max(surface[0], rect[0]) + l_y = max(surface[1], rect[1]) + width = min(surface[0] + surface[2], rect[0] + rect[2]) - l_x + height = min(surface[1] + surface[3], rect[1] + rect[3]) - l_y + if width < 0 or height < 0: + return (0, 0, 0, 0) + return (l_x, l_y, width, height) + + +def process_landmarks(r_x, r_y, r_w, r_h, landmarks): + """ Create points from result of inference of facial-landmarks network and size of input image + + Params: + r_x: x coordinate of top left corner of input image + r_y: y coordinate of top left corner of input image + r_w: width of input image + r_h: height of input image + landmarks: result of inference of facial-landmarks network + + Return: + Array of landmarks points for one face + """ + lmrks = landmarks[0] + raw_x = lmrks[::2] * r_w + r_x + raw_y = lmrks[1::2] * r_h + r_y + return np.array([[int(x), int(y)] for x, y in zip(raw_x, raw_y)]) + + +def eye_box(p_1, p_2, scale=1.8): + """ Get bounding box of eye + + Params: + p_1: point of left edge of eye + p_2: point of right edge of eye + scale: change size of box with this value + + Return: + Bounding box of eye and its midpoint + """ + + size = np.linalg.norm(p_1 - p_2) + midpoint = (p_1 + p_2) / 2 + width = scale * size + height = width + p_x = midpoint[0] - (width / 2) + p_y = midpoint[1] - (height / 2) + return (int(p_x), int(p_y), int(width), int(height)), list(map(int, midpoint)) + + +# ------------------------Custom graph operations------------------------ +@cv.gapi.op('custom.GProcessPoses', + in_types=[cv.GArray.GMat, cv.GArray.GMat, cv.GArray.GMat], + out_types=[cv.GArray.GMat]) +class GProcessPoses: + @staticmethod + def outMeta(arr_desc0, arr_desc1, arr_desc2): + return cv.empty_array_desc() + + +@cv.gapi.op('custom.GParseEyes', + in_types=[cv.GArray.GMat, cv.GArray.Rect, cv.GOpaque.Size], + out_types=[cv.GArray.Rect, cv.GArray.Rect, cv.GArray.Point, cv.GArray.Point]) +class GParseEyes: + @staticmethod + def outMeta(arr_desc0, arr_desc1, arr_desc2): + return cv.empty_array_desc(), cv.empty_array_desc(), \ + cv.empty_array_desc(), cv.empty_array_desc() + + +@cv.gapi.op('custom.GGetStates', + in_types=[cv.GArray.GMat, cv.GArray.GMat], + out_types=[cv.GArray.Int, cv.GArray.Int]) +class GGetStates: + @staticmethod + def outMeta(arr_desc0, arr_desc1): + return cv.empty_array_desc(), cv.empty_array_desc() + + +# ------------------------Custom kernels------------------------ +@cv.gapi.kernel(GProcessPoses) +class GProcessPosesImpl: + """ Custom kernel. Processed poses of heads + """ + @staticmethod + def run(in_ys, in_ps, in_rs): + """ Сustom kernel executable code + + Params: + in_ys: yaw angle of head + in_ps: pitch angle of head + in_rs: roll angle of head + + Return: + Arrays with heads poses + """ + out_poses = [] + size = len(in_ys) + for i in range(size): + out_poses.append(np.array([in_ys[i][0], in_ps[i][0], in_rs[i][0]]).T) + return out_poses + + +@cv.gapi.kernel(GParseEyes) +class GParseEyesImpl: + """ Custom kernel. Get information about eyes + """ + @staticmethod + def run(in_landm_per_face, in_face_rcs, frame_size): + """ Сustom kernel executable code + + Params: + in_landm_per_face: landmarks from inference of facial-landmarks network for each face + in_face_rcs: bounding boxes for each face + frame_size: size of input image + + Return: + Arrays of ROI for left and right eyes, array of midpoints and + array of landmarks points + """ + left_eyes = [] + right_eyes = [] + midpoints = [] + lmarks = [] + num_faces = len(in_landm_per_face) + surface = (0, 0, *frame_size) + for i in range(num_faces): + rect = in_face_rcs[i] + points = process_landmarks(*rect, in_landm_per_face[i]) + for p in points: + lmarks.append(p) + size = int(len(in_landm_per_face[i][0]) / 2) + + rect, midpoint_l = eye_box(lmarks[0 + i * size], lmarks[1 + i * size]) + left_eyes.append(intersection(surface, rect)) + rect, midpoint_r = eye_box(lmarks[2 + i * size], lmarks[3 + i * size]) + right_eyes.append(intersection(surface, rect)) + midpoints += [midpoint_l, midpoint_r] + return left_eyes, right_eyes, midpoints, lmarks + + +@cv.gapi.kernel(GGetStates) +class GGetStatesImpl: + """ Custom kernel. Get state of eye - open or closed + """ + @staticmethod + def run(eyesl, eyesr): + """ Сustom kernel executable code + + Params: + eyesl: result of inference of open-closed-eye network for left eye + eyesr: result of inference of open-closed-eye network for right eye + + Return: + States of left eyes and states of right eyes + """ + size = len(eyesl) + out_l_st = [] + out_r_st = [] + for i in range(size): + for st in eyesl[i]: + out_l_st += [1 if st[0] < st[1] else 0] + for st in eyesr[i]: + out_r_st += [1 if st[0] < st[1] else 0] + return out_l_st, out_r_st + + +if __name__ == '__main__': + ARGUMENTS = build_argparser().parse_args() + + # ------------------------Demo's graph------------------------ + g_in = cv.GMat() + + # Detect faces + face_inputs = cv.GInferInputs() + face_inputs.setInput('data', g_in) + face_outputs = cv.gapi.infer('face-detection', face_inputs) + faces = face_outputs.at('detection_out') + + # Parse faces + sz = cv.gapi.streaming.size(g_in) + faces_rc = cv.gapi.parseSSD(faces, sz, 0.5, False, False) + + # Detect poses + head_inputs = cv.GInferInputs() + head_inputs.setInput('data', g_in) + face_outputs = cv.gapi.infer('head-pose', faces_rc, head_inputs) + angles_y = face_outputs.at('angle_y_fc') + angles_p = face_outputs.at('angle_p_fc') + angles_r = face_outputs.at('angle_r_fc') + + # Parse poses + heads_pos = GProcessPoses.on(angles_y, angles_p, angles_r) + + # Detect landmarks + landmark_inputs = cv.GInferInputs() + landmark_inputs.setInput('data', g_in) + landmark_outputs = cv.gapi.infer('facial-landmarks', faces_rc, + landmark_inputs) + landmark = landmark_outputs.at('align_fc3') + + # Parse landmarks + left_eyes, right_eyes, mids, lmarks = GParseEyes.on(landmark, faces_rc, sz) + + # Detect eyes + eyes_inputs = cv.GInferInputs() + eyes_inputs.setInput('input.1', g_in) + eyesl_outputs = cv.gapi.infer('open-closed-eye', left_eyes, eyes_inputs) + eyesr_outputs = cv.gapi.infer('open-closed-eye', right_eyes, eyes_inputs) + eyesl = eyesl_outputs.at('19') + eyesr = eyesr_outputs.at('19') + + # Process eyes states + l_eye_st, r_eye_st = GGetStates.on(eyesl, eyesr) + + # Gaze estimation + gaze_inputs = cv.GInferListInputs() + gaze_inputs.setInput('left_eye_image', left_eyes) + gaze_inputs.setInput('right_eye_image', right_eyes) + gaze_inputs.setInput('head_pose_angles', heads_pos) + gaze_outputs = cv.gapi.infer2('gaze-estimation', g_in, gaze_inputs) + gaze_vectors = gaze_outputs.at('gaze_vector') + + out = cv.gapi.copy(g_in) + # ------------------------End of graph------------------------ + + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(out, + faces_rc, + left_eyes, + right_eyes, + gaze_vectors, + angles_y, + angles_p, + angles_r, + l_eye_st, + r_eye_st, + mids, + lmarks)) + + # Networks + face_net = cv.gapi.ie.params('face-detection', ARGUMENTS.facem, + weight_path(ARGUMENTS.facem), ARGUMENTS.faced) + head_pose_net = cv.gapi.ie.params('head-pose', ARGUMENTS.headm, + weight_path(ARGUMENTS.headm), ARGUMENTS.headd) + landmarks_net = cv.gapi.ie.params('facial-landmarks', ARGUMENTS.landm, + weight_path(ARGUMENTS.landm), ARGUMENTS.landd) + gaze_net = cv.gapi.ie.params('gaze-estimation', ARGUMENTS.gazem, + weight_path(ARGUMENTS.gazem), ARGUMENTS.gazed) + eye_net = cv.gapi.ie.params('open-closed-eye', ARGUMENTS.eyem, + weight_path(ARGUMENTS.eyem), ARGUMENTS.eyed) + + nets = cv.gapi.networks(face_net, head_pose_net, landmarks_net, gaze_net, eye_net) + + # Kernels pack + kernels = cv.gapi.kernels(GParseEyesImpl, GProcessPosesImpl, GGetStatesImpl) + + # ------------------------Execution part------------------------ + ccomp = comp.compileStreaming(args=cv.gapi.compile_args(kernels, nets)) + source = cv.gapi.wip.make_capture_src(ARGUMENTS.input) + ccomp.setSource(cv.gin(source)) + ccomp.start() + + frames = 0 + fps = 0 + print('Processing') + START_TIME = time.time() + + while True: + start_time_cycle = time.time() + has_frame, (oimg, + outr, + l_eyes, + r_eyes, + outg, + out_y, + out_p, + out_r, + out_st_l, + out_st_r, + out_mids, + outl) = ccomp.pull() + + if not has_frame: + break + + # Draw + GREEN = (0, 255, 0) + RED = (0, 0, 255) + WHITE = (255, 255, 255) + BLUE = (255, 0, 0) + PINK = (255, 0, 255) + YELLOW = (0, 255, 255) + + M_PI_180 = np.pi / 180 + M_PI_2 = np.pi / 2 + M_PI = np.pi + + FACES_SIZE = len(outr) + + for i, out_rect in enumerate(outr): + # Face box + cv.rectangle(oimg, out_rect, WHITE, 1) + rx, ry, rwidth, rheight = out_rect + + # Landmarks + lm_radius = int(0.01 * rwidth + 1) + lmsize = int(len(outl) / FACES_SIZE) + for j in range(lmsize): + cv.circle(oimg, outl[j + i * lmsize], lm_radius, YELLOW, -1) + + # Headposes + yaw = out_y[i] + pitch = out_p[i] + roll = out_r[i] + sin_y = np.sin(yaw[:] * M_PI_180) + sin_p = np.sin(pitch[:] * M_PI_180) + sin_r = np.sin(roll[:] * M_PI_180) + + cos_y = np.cos(yaw[:] * M_PI_180) + cos_p = np.cos(pitch[:] * M_PI_180) + cos_r = np.cos(roll[:] * M_PI_180) + + axis_length = 0.4 * rwidth + x_center = int(rx + rwidth / 2) + y_center = int(ry + rheight / 2) + + # center to right + cv.line(oimg, [x_center, y_center], + [int(x_center + axis_length * (cos_r * cos_y + sin_y * sin_p * sin_r)), + int(y_center + axis_length * cos_p * sin_r)], + RED, 2) + + # center to top + cv.line(oimg, [x_center, y_center], + [int(x_center + axis_length * (cos_r * sin_y * sin_p + cos_y * sin_r)), + int(y_center - axis_length * cos_p * cos_r)], + GREEN, 2) + + # center to forward + cv.line(oimg, [x_center, y_center], + [int(x_center + axis_length * sin_y * cos_p), + int(y_center + axis_length * sin_p)], + PINK, 2) + + scale_box = 0.002 * rwidth + cv.putText(oimg, "head pose: (y=%0.0f, p=%0.0f, r=%0.0f)" % + (np.round(yaw), np.round(pitch), np.round(roll)), + [int(rx), int(ry + rheight + 5 * rwidth / 100)], + cv.FONT_HERSHEY_PLAIN, scale_box * 2, WHITE, 1) + + # Eyes boxes + color_l = GREEN if out_st_l[i] else RED + cv.rectangle(oimg, l_eyes[i], color_l, 1) + color_r = GREEN if out_st_r[i] else RED + cv.rectangle(oimg, r_eyes[i], color_r, 1) + + # Gaze vectors + norm_gazes = np.linalg.norm(outg[i][0]) + gaze_vector = outg[i][0] / norm_gazes + + arrow_length = 0.4 * rwidth + gaze_arrow = [arrow_length * gaze_vector[0], -arrow_length * gaze_vector[1]] + left_arrow = [int(a+b) for a, b in zip(out_mids[0 + i * 2], gaze_arrow)] + right_arrow = [int(a+b) for a, b in zip(out_mids[1 + i * 2], gaze_arrow)] + if out_st_l[i]: + cv.arrowedLine(oimg, out_mids[0 + i * 2], left_arrow, BLUE, 2) + if out_st_r[i]: + cv.arrowedLine(oimg, out_mids[1 + i * 2], right_arrow, BLUE, 2) + + v0, v1, v2 = outg[i][0] + + gaze_angles = [180 / M_PI * (M_PI_2 + np.arctan2(v2, v0)), + 180 / M_PI * (M_PI_2 - np.arccos(v1 / norm_gazes))] + cv.putText(oimg, "gaze angles: (h=%0.0f, v=%0.0f)" % + (np.round(gaze_angles[0]), np.round(gaze_angles[1])), + [int(rx), int(ry + rheight + 12 * rwidth / 100)], + cv.FONT_HERSHEY_PLAIN, scale_box * 2, WHITE, 1) + + # Add FPS value to frame + cv.putText(oimg, "FPS: %0i" % (fps), [int(20), int(40)], + cv.FONT_HERSHEY_PLAIN, 2, RED, 2) + + # Show result + cv.imshow('Gaze Estimation', oimg) + + fps = int(1. / (time.time() - start_time_cycle)) + frames += 1 + EXECUTION_TIME = time.time() - START_TIME + print('Execution successful') + print('Mean FPS is ', int(frames / EXECUTION_TIME)) diff --git a/modules/gapi/misc/python/shadow_gapi.hpp b/modules/gapi/misc/python/shadow_gapi.hpp index bb820020698a..0b489dde0f55 100644 --- a/modules/gapi/misc/python/shadow_gapi.hpp +++ b/modules/gapi/misc/python/shadow_gapi.hpp @@ -3,65 +3,80 @@ namespace cv { - struct GAPI_EXPORTS_W_SIMPLE GCompileArg { }; - - GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage pkg); - GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GNetPackage pkg); - GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage kernels, gapi::GNetPackage nets); +struct GAPI_EXPORTS_W_SIMPLE GCompileArg +{ + GAPI_WRAP GCompileArg(gapi::GKernelPackage pkg); + GAPI_WRAP GCompileArg(gapi::GNetPackage pkg); +}; - // NB: This classes doesn't exist in *.so - // HACK: Mark them as a class to force python wrapper generate code for this entities - class GAPI_EXPORTS_W_SIMPLE GProtoArg { }; - class GAPI_EXPORTS_W_SIMPLE GProtoInputArgs { }; - class GAPI_EXPORTS_W_SIMPLE GProtoOutputArgs { }; - class GAPI_EXPORTS_W_SIMPLE GRunArg { }; - class GAPI_EXPORTS_W_SIMPLE GMetaArg { GAPI_WRAP GMetaArg(); }; +class GAPI_EXPORTS_W_SIMPLE GInferInputs +{ +public: + GAPI_WRAP GInferInputs(); + GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GMat& value); + GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GFrame& value); +}; - using GProtoInputArgs = GIOProtoArgs; - using GProtoOutputArgs = GIOProtoArgs; +class GAPI_EXPORTS_W_SIMPLE GInferListInputs +{ +public: + GAPI_WRAP GInferListInputs(); + GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray& value); + GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray& value); +}; - class GAPI_EXPORTS_W_SIMPLE GInferInputs - { - public: - GAPI_WRAP GInferInputs(); - GAPI_WRAP void setInput(const std::string& name, const cv::GMat& value); - GAPI_WRAP void setInput(const std::string& name, const cv::GFrame& value); - }; +class GAPI_EXPORTS_W_SIMPLE GInferOutputs +{ +public: + GAPI_WRAP GInferOutputs(); + GAPI_WRAP cv::GMat at(const std::string& name); +}; - class GAPI_EXPORTS_W_SIMPLE GInferListInputs - { - public: - GAPI_WRAP GInferListInputs(); - GAPI_WRAP void setInput(const std::string& name, const cv::GArray& value); - GAPI_WRAP void setInput(const std::string& name, const cv::GArray& value); - }; +class GAPI_EXPORTS_W_SIMPLE GInferListOutputs +{ +public: + GAPI_WRAP GInferListOutputs(); + GAPI_WRAP cv::GArray at(const std::string& name); +}; - class GAPI_EXPORTS_W_SIMPLE GInferOutputs - { - public: - GAPI_WRAP GInferOutputs(); - GAPI_WRAP cv::GMat at(const std::string& name); - }; +namespace gapi +{ +namespace wip +{ +class GAPI_EXPORTS_W IStreamSource { }; +namespace draw +{ + // NB: These render primitives are partially wrapped in shadow file + // because cv::Rect conflicts with cv::gapi::wip::draw::Rect in python generator + // and cv::Rect2i breaks standalone mode. + struct Rect + { + GAPI_WRAP Rect(const cv::Rect2i& rect_, + const cv::Scalar& color_, + int thick_ = 1, + int lt_ = 8, + int shift_ = 0); + }; - class GAPI_EXPORTS_W_SIMPLE GInferListOutputs - { - public: - GAPI_WRAP GInferListOutputs(); - GAPI_WRAP cv::GArray at(const std::string& name); - }; + struct Mosaic + { + GAPI_WRAP Mosaic(const cv::Rect2i& mos_, int cellSz_, int decim_); + }; +} // namespace draw +} // namespace wip +namespace streaming +{ + // FIXME: Extend to work with an arbitrary G-type. + cv::GOpaque GAPI_EXPORTS_W timestamp(cv::GMat); + cv::GOpaque GAPI_EXPORTS_W seqNo(cv::GMat); + cv::GOpaque GAPI_EXPORTS_W seq_id(cv::GMat); - namespace detail - { - struct GAPI_EXPORTS_W_SIMPLE ExtractArgsCallback { }; - struct GAPI_EXPORTS_W_SIMPLE ExtractMetaCallback { }; - } // namespace detail + GAPI_EXPORTS_W cv::GMat desync(const cv::GMat &g); +} // namespace streaming +} // namespace gapi - namespace gapi - { - GAPI_EXPORTS_W gapi::GNetPackage networks(const cv::gapi::ie::PyParams& params); - namespace wip - { - class GAPI_EXPORTS_W IStreamSource { }; - } // namespace wip - } // namespace gapi +namespace detail +{ + gapi::GNetParam GAPI_EXPORTS_W strip(gapi::ie::PyParams params); +} // namespace detail } // namespace cv diff --git a/modules/gapi/misc/python/test/test_gapi_core.py b/modules/gapi/misc/python/test/test_gapi_core.py index 814d05d7cde4..780558d98b1a 100644 --- a/modules/gapi/misc/python/test/test_gapi_core.py +++ b/modules/gapi/misc/python/test/test_gapi_core.py @@ -3,187 +3,209 @@ import numpy as np import cv2 as cv import os +import sys +import unittest from tests_common import NewOpenCVTests -# Plaidml is an optional backend -pkgs = [ - ('ocl' , cv.gapi.core.ocl.kernels()), - ('cpu' , cv.gapi.core.cpu.kernels()), - ('fluid' , cv.gapi.core.fluid.kernels()) - # ('plaidml', cv.gapi.core.plaidml.kernels()) - ] +try: + if sys.version_info[:2] < (3, 0): + raise unittest.SkipTest('Python 2.x is not supported') -class gapi_core_test(NewOpenCVTests): + # Plaidml is an optional backend + pkgs = [ + ('ocl' , cv.gapi.core.ocl.kernels()), + ('cpu' , cv.gapi.core.cpu.kernels()), + ('fluid' , cv.gapi.core.fluid.kernels()) + # ('plaidml', cv.gapi.core.plaidml.kernels()) + ] - def test_add(self): - # TODO: Extend to use any type and size here - sz = (720, 1280) - in1 = np.full(sz, 100) - in2 = np.full(sz, 50) - # OpenCV - expected = cv.add(in1, in2) + class gapi_core_test(NewOpenCVTests): - # G-API - g_in1 = cv.GMat() - g_in2 = cv.GMat() - g_out = cv.gapi.add(g_in1, g_in2) - comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out)) + def test_add(self): + # TODO: Extend to use any type and size here + sz = (720, 1280) + in1 = np.full(sz, 100) + in2 = np.full(sz, 50) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(in1, in2), args=cv.compile_args(pkg)) - # Comparison - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') - self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend') + # OpenCV + expected = cv.add(in1, in2) + # G-API + g_in1 = cv.GMat() + g_in2 = cv.GMat() + g_out = cv.gapi.add(g_in1, g_in2) + comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out)) + + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(in1, in2), args=cv.gapi.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') + self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend') + + + def test_add_uint8(self): + sz = (720, 1280) + in1 = np.full(sz, 100, dtype=np.uint8) + in2 = np.full(sz, 50 , dtype=np.uint8) + + # OpenCV + expected = cv.add(in1, in2) + + # G-API + g_in1 = cv.GMat() + g_in2 = cv.GMat() + g_out = cv.gapi.add(g_in1, g_in2) + comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out)) + + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(in1, in2), args=cv.gapi.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') + self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend') - def test_add_uint8(self): - sz = (720, 1280) - in1 = np.full(sz, 100, dtype=np.uint8) - in2 = np.full(sz, 50 , dtype=np.uint8) - # OpenCV - expected = cv.add(in1, in2) + def test_mean(self): + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + in_mat = cv.imread(img_path) - # G-API - g_in1 = cv.GMat() - g_in2 = cv.GMat() - g_out = cv.gapi.add(g_in1, g_in2) - comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out)) + # OpenCV + expected = cv.mean(in_mat) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(in1, in2), args=cv.compile_args(pkg)) - # Comparison - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') - self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend') + # G-API + g_in = cv.GMat() + g_out = cv.gapi.mean(g_in) + comp = cv.GComputation(g_in, g_out) + + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') - def test_mean(self): - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - in_mat = cv.imread(img_path) + def test_split3(self): + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + in_mat = cv.imread(img_path) - # OpenCV - expected = cv.mean(in_mat) + # OpenCV + expected = cv.split(in_mat) - # G-API - g_in = cv.GMat() - g_out = cv.gapi.mean(g_in) - comp = cv.GComputation(g_in, g_out) + # G-API + g_in = cv.GMat() + b, g, r = cv.gapi.split3(g_in) + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r)) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg)) - # Comparison - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg)) + # Comparison + for e, a in zip(expected, actual): + self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') + self.assertEqual(e.dtype, a.dtype, 'Failed on ' + pkg_name + ' backend') - def test_split3(self): - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - in_mat = cv.imread(img_path) + def test_threshold(self): + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY) + maxv = (30, 30) - # OpenCV - expected = cv.split(in_mat) + # OpenCV + expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE) - # G-API - g_in = cv.GMat() - b, g, r = cv.gapi.split3(g_in) - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r)) + # G-API + g_in = cv.GMat() + g_sc = cv.GScalar() + mat, threshold = cv.gapi.threshold(g_in, g_sc, cv.THRESH_TRIANGLE) + comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(mat, threshold)) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg)) - # Comparison - for e, a in zip(expected, actual): - self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF), + for pkg_name, pkg in pkgs: + actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.gapi.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected_mat, actual_mat, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') + self.assertEqual(expected_mat.dtype, actual_mat.dtype, + 'Failed on ' + pkg_name + ' backend') + self.assertEqual(expected_thresh, actual_thresh[0], 'Failed on ' + pkg_name + ' backend') - self.assertEqual(e.dtype, a.dtype, 'Failed on ' + pkg_name + ' backend') - - - def test_threshold(self): - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY) - maxv = (30, 30) - - # OpenCV - expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE) - - # G-API - g_in = cv.GMat() - g_sc = cv.GScalar() - mat, threshold = cv.gapi.threshold(g_in, g_sc, cv.THRESH_TRIANGLE) - comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(mat, threshold)) - - for pkg_name, pkg in pkgs: - actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.compile_args(pkg)) - # Comparison - self.assertEqual(0.0, cv.norm(expected_mat, actual_mat, cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') - self.assertEqual(expected_mat.dtype, actual_mat.dtype, - 'Failed on ' + pkg_name + ' backend') - self.assertEqual(expected_thresh, actual_thresh[0], - 'Failed on ' + pkg_name + ' backend') - - def test_kmeans(self): - # K-means params - count = 100 - sz = (count, 2) - in_mat = np.random.random(sz).astype(np.float32) - K = 5 - flags = cv.KMEANS_RANDOM_CENTERS - attempts = 1; - criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0) - - # G-API - g_in = cv.GMat() - compactness, out_labels, centers = cv.gapi.kmeans(g_in, K, criteria, attempts, flags) - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(compactness, out_labels, centers)) - - compact, labels, centers = comp.apply(cv.gin(in_mat)) - - # Assert - self.assertTrue(compact >= 0) - self.assertEqual(sz[0], labels.shape[0]) - self.assertEqual(1, labels.shape[1]) - self.assertTrue(labels.size != 0) - self.assertEqual(centers.shape[1], sz[1]); - self.assertEqual(centers.shape[0], K); - self.assertTrue(centers.size != 0); - - - def generate_random_points(self, sz): - arr = np.random.random(sz).astype(np.float32).T - return list(zip(arr[0], arr[1])) - - - def test_kmeans_2d(self): - # K-means 2D params - count = 100 - sz = (count, 2) - amount = sz[0] - K = 5 - flags = cv.KMEANS_RANDOM_CENTERS - attempts = 1; - criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0); - in_vector = self.generate_random_points(sz) - in_labels = [] - - # G-API - data = cv.GArrayT(cv.gapi.CV_POINT2F) - best_labels = cv.GArrayT(cv.gapi.CV_INT) - - compactness, out_labels, centers = cv.gapi.kmeans(data, K, best_labels, criteria, attempts, flags); - comp = cv.GComputation(cv.GIn(data, best_labels), cv.GOut(compactness, out_labels, centers)); - - compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels)); - - # Assert - self.assertTrue(compact >= 0) - self.assertEqual(amount, len(labels)) - self.assertEqual(K, len(centers)) + + + def test_kmeans(self): + # K-means params + count = 100 + sz = (count, 2) + in_mat = np.random.random(sz).astype(np.float32) + K = 5 + flags = cv.KMEANS_RANDOM_CENTERS + attempts = 1 + criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0) + + # G-API + g_in = cv.GMat() + compactness, out_labels, centers = cv.gapi.kmeans(g_in, K, criteria, attempts, flags) + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(compactness, out_labels, centers)) + + compact, labels, centers = comp.apply(cv.gin(in_mat)) + + # Assert + self.assertTrue(compact >= 0) + self.assertEqual(sz[0], labels.shape[0]) + self.assertEqual(1, labels.shape[1]) + self.assertTrue(labels.size != 0) + self.assertEqual(centers.shape[1], sz[1]) + self.assertEqual(centers.shape[0], K) + self.assertTrue(centers.size != 0) + + + def generate_random_points(self, sz): + arr = np.random.random(sz).astype(np.float32).T + return list(zip(arr[0], arr[1])) + + + def test_kmeans_2d(self): + # K-means 2D params + count = 100 + sz = (count, 2) + amount = sz[0] + K = 5 + flags = cv.KMEANS_RANDOM_CENTERS + attempts = 1 + criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0) + in_vector = self.generate_random_points(sz) + in_labels = [] + + # G-API + data = cv.GArrayT(cv.gapi.CV_POINT2F) + best_labels = cv.GArrayT(cv.gapi.CV_INT) + + compactness, out_labels, centers = cv.gapi.kmeans(data, K, best_labels, criteria, attempts, flags) + comp = cv.GComputation(cv.GIn(data, best_labels), cv.GOut(compactness, out_labels, centers)) + + compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels)) + + # Assert + self.assertTrue(compact >= 0) + self.assertEqual(amount, len(labels)) + self.assertEqual(K, len(centers)) + + +except unittest.SkipTest as e: + + message = str(e) + + class TestSkip(unittest.TestCase): + def setUp(self): + self.skipTest('Skip tests: ' + message) + + def test_skip(): + pass + + pass if __name__ == '__main__': diff --git a/modules/gapi/misc/python/test/test_gapi_imgproc.py b/modules/gapi/misc/python/test/test_gapi_imgproc.py index ed6f883fe55f..365a5a8cca74 100644 --- a/modules/gapi/misc/python/test/test_gapi_imgproc.py +++ b/modules/gapi/misc/python/test/test_gapi_imgproc.py @@ -3,103 +3,124 @@ import numpy as np import cv2 as cv import os +import sys +import unittest from tests_common import NewOpenCVTests -# Plaidml is an optional backend -pkgs = [ - ('ocl' , cv.gapi.core.ocl.kernels()), - ('cpu' , cv.gapi.core.cpu.kernels()), - ('fluid' , cv.gapi.core.fluid.kernels()) - # ('plaidml', cv.gapi.core.plaidml.kernels()) - ] +try: + if sys.version_info[:2] < (3, 0): + raise unittest.SkipTest('Python 2.x is not supported') -class gapi_imgproc_test(NewOpenCVTests): + # Plaidml is an optional backend + pkgs = [ + ('ocl' , cv.gapi.core.ocl.kernels()), + ('cpu' , cv.gapi.core.cpu.kernels()), + ('fluid' , cv.gapi.core.fluid.kernels()) + # ('plaidml', cv.gapi.core.plaidml.kernels()) + ] - def test_good_features_to_track(self): - # TODO: Extend to use any type and size here - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY) - # NB: goodFeaturesToTrack configuration - max_corners = 50 - quality_lvl = 0.01 - min_distance = 10 - block_sz = 3 - use_harris_detector = True - k = 0.04 - mask = None + class gapi_imgproc_test(NewOpenCVTests): - # OpenCV - expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl, - min_distance, mask=mask, - blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k) + def test_good_features_to_track(self): + # TODO: Extend to use any type and size here + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY) - # G-API - g_in = cv.GMat() - g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl, - min_distance, mask, block_sz, use_harris_detector, k) + # NB: goodFeaturesToTrack configuration + max_corners = 50 + quality_lvl = 0.01 + min_distance = 10 + block_sz = 3 + use_harris_detector = True + k = 0.04 + mask = None - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) + # OpenCV + expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl, + min_distance, mask=mask, + blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(in1), args=cv.compile_args(pkg)) - # NB: OpenCV & G-API have different output shapes: - # OpenCV - (num_points, 1, 2) - # G-API - (num_points, 2) - # Comparison - self.assertEqual(0.0, cv.norm(expected.flatten(), - np.array(actual, dtype=np.float32).flatten(), - cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') + # G-API + g_in = cv.GMat() + g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl, + min_distance, mask, block_sz, use_harris_detector, k) + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) - def test_rgb2gray(self): - # TODO: Extend to use any type and size here - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - in1 = cv.imread(img_path) + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg)) + # NB: OpenCV & G-API have different output shapes: + # OpenCV - (num_points, 1, 2) + # G-API - (num_points, 2) + # Comparison + self.assertEqual(0.0, cv.norm(expected.flatten(), + np.array(actual, dtype=np.float32).flatten(), + cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') - # OpenCV - expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY) - # G-API - g_in = cv.GMat() - g_out = cv.gapi.RGB2Gray(g_in) + def test_rgb2gray(self): + # TODO: Extend to use any type and size here + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + in1 = cv.imread(img_path) - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) + # OpenCV + expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(in1), args=cv.compile_args(pkg)) - # Comparison - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') + # G-API + g_in = cv.GMat() + g_out = cv.gapi.RGB2Gray(g_in) + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) - def test_bounding_rect(self): - sz = 1280 - fscale = 256 + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') - def sample_value(fscale): - return np.random.uniform(0, 255 * fscale) / fscale - points = np.array([(sample_value(fscale), sample_value(fscale)) for _ in range(1280)], np.float32) + def test_bounding_rect(self): + sz = 1280 + fscale = 256 - # OpenCV - expected = cv.boundingRect(points) + def sample_value(fscale): + return np.random.uniform(0, 255 * fscale) / fscale - # G-API - g_in = cv.GMat() - g_out = cv.gapi.boundingRect(g_in) + points = np.array([(sample_value(fscale), sample_value(fscale)) for _ in range(1280)], np.float32) - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) + # OpenCV + expected = cv.boundingRect(points) - for pkg_name, pkg in pkgs: - actual = comp.apply(cv.gin(points), args=cv.compile_args(pkg)) - # Comparison - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), - 'Failed on ' + pkg_name + ' backend') + # G-API + g_in = cv.GMat() + g_out = cv.gapi.boundingRect(g_in) + + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) + + for pkg_name, pkg in pkgs: + actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg)) + # Comparison + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF), + 'Failed on ' + pkg_name + ' backend') + + +except unittest.SkipTest as e: + + message = str(e) + + class TestSkip(unittest.TestCase): + def setUp(self): + self.skipTest('Skip tests: ' + message) + + def test_skip(): + pass + + pass if __name__ == '__main__': diff --git a/modules/gapi/misc/python/test/test_gapi_infer.py b/modules/gapi/misc/python/test/test_gapi_infer.py index db048f57866c..8ecc957e416d 100644 --- a/modules/gapi/misc/python/test/test_gapi_infer.py +++ b/modules/gapi/misc/python/test/test_gapi_infer.py @@ -3,318 +3,338 @@ import numpy as np import cv2 as cv import os +import sys +import unittest from tests_common import NewOpenCVTests -class test_gapi_infer(NewOpenCVTests): +try: - def infer_reference_network(self, model_path, weights_path, img): - net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path) - net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE) - net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) + if sys.version_info[:2] < (3, 0): + raise unittest.SkipTest('Python 2.x is not supported') - blob = cv.dnn.blobFromImage(img) - net.setInput(blob) - return net.forward(net.getUnconnectedOutLayersNames()) + class test_gapi_infer(NewOpenCVTests): + def infer_reference_network(self, model_path, weights_path, img): + net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path) + net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE) + net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) - def make_roi(self, img, roi): - return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...] + blob = cv.dnn.blobFromImage(img) + net.setInput(blob) + return net.forward(net.getUnconnectedOutLayersNames()) - def test_age_gender_infer(self): - # NB: Check IE - if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): - return - root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' - model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - device_id = 'CPU' + def make_roi(self, img, roi): + return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...] - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - img = cv.resize(cv.imread(img_path), (62,62)) - # OpenCV DNN - dnn_age, dnn_gender = self.infer_reference_network(model_path, weights_path, img) + def test_age_gender_infer(self): + # NB: Check IE + if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): + return - # OpenCV G-API - g_in = cv.GMat() - inputs = cv.GInferInputs() - inputs.setInput('data', g_in) + root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' + model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + device_id = 'CPU' - outputs = cv.gapi.infer("net", inputs) - age_g = outputs.at("age_conv3") - gender_g = outputs.at("prob") + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + img = cv.resize(cv.imread(img_path), (62,62)) - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(age_g, gender_g)) - pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) + # OpenCV DNN + dnn_age, dnn_gender = self.infer_reference_network(model_path, weights_path, img) - gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.compile_args(cv.gapi.networks(pp))) + # OpenCV G-API + g_in = cv.GMat() + inputs = cv.GInferInputs() + inputs.setInput('data', g_in) - # Check - self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) - self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) + outputs = cv.gapi.infer("net", inputs) + age_g = outputs.at("age_conv3") + gender_g = outputs.at("prob") + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(age_g, gender_g)) + pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) - def test_age_gender_infer_roi(self): - # NB: Check IE - if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): - return + gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.gapi.compile_args(cv.gapi.networks(pp))) - root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' - model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - device_id = 'CPU' + # Check + self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) + self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - img = cv.imread(img_path) - roi = (10, 10, 62, 62) - # OpenCV DNN - dnn_age, dnn_gender = self.infer_reference_network(model_path, - weights_path, - self.make_roi(img, roi)) + def test_age_gender_infer_roi(self): + # NB: Check IE + if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): + return - # OpenCV G-API - g_in = cv.GMat() - g_roi = cv.GOpaqueT(cv.gapi.CV_RECT) - inputs = cv.GInferInputs() - inputs.setInput('data', g_in) - - outputs = cv.gapi.infer("net", g_roi, inputs) - age_g = outputs.at("age_conv3") - gender_g = outputs.at("prob") - - comp = cv.GComputation(cv.GIn(g_in, g_roi), cv.GOut(age_g, gender_g)) - pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) - - gapi_age, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.compile_args(cv.gapi.networks(pp))) - - # Check - self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) - self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) - - - def test_age_gender_infer_roi_list(self): - # NB: Check IE - if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): - return - - root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' - model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - device_id = 'CPU' - - rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)] - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - img = cv.imread(img_path) - - # OpenCV DNN - dnn_age_list = [] - dnn_gender_list = [] - for roi in rois: - age, gender = self.infer_reference_network(model_path, - weights_path, - self.make_roi(img, roi)) - dnn_age_list.append(age) - dnn_gender_list.append(gender) - - # OpenCV G-API - g_in = cv.GMat() - g_rois = cv.GArrayT(cv.gapi.CV_RECT) - inputs = cv.GInferInputs() - inputs.setInput('data', g_in) - - outputs = cv.gapi.infer("net", g_rois, inputs) - age_g = outputs.at("age_conv3") - gender_g = outputs.at("prob") - - comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g)) - pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) - - gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois), - args=cv.compile_args(cv.gapi.networks(pp))) - - # Check - for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list, - gapi_gender_list, - dnn_age_list, - dnn_gender_list): - self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) - self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) + root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' + model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + device_id = 'CPU' + + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + img = cv.imread(img_path) + roi = (10, 10, 62, 62) + + # OpenCV DNN + dnn_age, dnn_gender = self.infer_reference_network(model_path, + weights_path, + self.make_roi(img, roi)) + + # OpenCV G-API + g_in = cv.GMat() + g_roi = cv.GOpaqueT(cv.gapi.CV_RECT) + inputs = cv.GInferInputs() + inputs.setInput('data', g_in) + + outputs = cv.gapi.infer("net", g_roi, inputs) + age_g = outputs.at("age_conv3") + gender_g = outputs.at("prob") + + comp = cv.GComputation(cv.GIn(g_in, g_roi), cv.GOut(age_g, gender_g)) + pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) + gapi_age, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.gapi.compile_args(cv.gapi.networks(pp))) - def test_age_gender_infer2_roi(self): - # NB: Check IE - if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): - return - - root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' - model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - device_id = 'CPU' - - rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)] - img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - img = cv.imread(img_path) - - # OpenCV DNN - dnn_age_list = [] - dnn_gender_list = [] - for roi in rois: - age, gender = self.infer_reference_network(model_path, - weights_path, - self.make_roi(img, roi)) - dnn_age_list.append(age) - dnn_gender_list.append(gender) - - # OpenCV G-API - g_in = cv.GMat() - g_rois = cv.GArrayT(cv.gapi.CV_RECT) - inputs = cv.GInferListInputs() - inputs.setInput('data', g_rois) - - outputs = cv.gapi.infer2("net", g_in, inputs) - age_g = outputs.at("age_conv3") - gender_g = outputs.at("prob") - - comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g)) - pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) - - gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois), - args=cv.compile_args(cv.gapi.networks(pp))) - - # Check - for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list, - gapi_gender_list, - dnn_age_list, - dnn_gender_list): + # Check self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) + def test_age_gender_infer_roi_list(self): + # NB: Check IE + if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): + return + + root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' + model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + device_id = 'CPU' + + rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)] + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + img = cv.imread(img_path) + + # OpenCV DNN + dnn_age_list = [] + dnn_gender_list = [] + for roi in rois: + age, gender = self.infer_reference_network(model_path, + weights_path, + self.make_roi(img, roi)) + dnn_age_list.append(age) + dnn_gender_list.append(gender) + + # OpenCV G-API + g_in = cv.GMat() + g_rois = cv.GArrayT(cv.gapi.CV_RECT) + inputs = cv.GInferInputs() + inputs.setInput('data', g_in) + + outputs = cv.gapi.infer("net", g_rois, inputs) + age_g = outputs.at("age_conv3") + gender_g = outputs.at("prob") + + comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g)) + pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) + + gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois), + args=cv.gapi.compile_args(cv.gapi.networks(pp))) + + # Check + for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list, + gapi_gender_list, + dnn_age_list, + dnn_gender_list): + self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) + self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) + + + def test_age_gender_infer2_roi(self): + # NB: Check IE + if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): + return + + root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' + model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + device_id = 'CPU' + + rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)] + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + img = cv.imread(img_path) + + # OpenCV DNN + dnn_age_list = [] + dnn_gender_list = [] + for roi in rois: + age, gender = self.infer_reference_network(model_path, + weights_path, + self.make_roi(img, roi)) + dnn_age_list.append(age) + dnn_gender_list.append(gender) + + # OpenCV G-API + g_in = cv.GMat() + g_rois = cv.GArrayT(cv.gapi.CV_RECT) + inputs = cv.GInferListInputs() + inputs.setInput('data', g_rois) + + outputs = cv.gapi.infer2("net", g_in, inputs) + age_g = outputs.at("age_conv3") + gender_g = outputs.at("prob") + + comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g)) + pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) + + gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois), + args=cv.gapi.compile_args(cv.gapi.networks(pp))) + + # Check + for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list, + gapi_gender_list, + dnn_age_list, + dnn_gender_list): + self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF)) + self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF)) + + + + def test_person_detection_retail_0013(self): + # NB: Check IE + if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): + return + + root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013' + model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + device_id = 'CPU' + img = cv.resize(cv.imread(img_path), (544, 320)) + + # OpenCV DNN + net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path) + net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE) + net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) + + blob = cv.dnn.blobFromImage(img) + + def parseSSD(detections, size): + h, w = size + bboxes = [] + detections = detections.reshape(-1, 7) + for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections: + if confidence >= 0.5: + x = int(xmin * w) + y = int(ymin * h) + width = int(xmax * w - x) + height = int(ymax * h - y) + bboxes.append((x, y, width, height)) + + return bboxes + + net.setInput(blob) + dnn_detections = net.forward() + dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2]) + + # OpenCV G-API + g_in = cv.GMat() + inputs = cv.GInferInputs() + inputs.setInput('data', g_in) + + g_sz = cv.gapi.streaming.size(g_in) + outputs = cv.gapi.infer("net", inputs) + detections = outputs.at("detection_out") + bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False) + + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes)) + pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) + + gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)), + args=cv.gapi.compile_args(cv.gapi.networks(pp))) + + # Comparison + self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(), + np.array(gapi_boxes).flatten(), + cv.NORM_INF)) + + + def test_person_detection_retail_0013(self): + # NB: Check IE + if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): + return + + root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013' + model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) + img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + device_id = 'CPU' + img = cv.resize(cv.imread(img_path), (544, 320)) + + # OpenCV DNN + net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path) + net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE) + net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) + + blob = cv.dnn.blobFromImage(img) + + def parseSSD(detections, size): + h, w = size + bboxes = [] + detections = detections.reshape(-1, 7) + for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections: + if confidence >= 0.5: + x = int(xmin * w) + y = int(ymin * h) + width = int(xmax * w - x) + height = int(ymax * h - y) + bboxes.append((x, y, width, height)) + + return bboxes + + net.setInput(blob) + dnn_detections = net.forward() + dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2]) + + # OpenCV G-API + g_in = cv.GMat() + inputs = cv.GInferInputs() + inputs.setInput('data', g_in) + + g_sz = cv.gapi.streaming.size(g_in) + outputs = cv.gapi.infer("net", inputs) + detections = outputs.at("detection_out") + bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False) + + comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes)) + pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) + + gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)), + args=cv.gapi.compile_args(cv.gapi.networks(pp))) + + # Comparison + self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(), + np.array(gapi_boxes).flatten(), + cv.NORM_INF)) + + +except unittest.SkipTest as e: + + message = str(e) + + class TestSkip(unittest.TestCase): + def setUp(self): + self.skipTest('Skip tests: ' + message) + + def test_skip(): + pass - def test_person_detection_retail_0013(self): - # NB: Check IE - if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): - return - - root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013' - model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - device_id = 'CPU' - img = cv.resize(cv.imread(img_path), (544, 320)) - - # OpenCV DNN - net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path) - net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE) - net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) - - blob = cv.dnn.blobFromImage(img) - - def parseSSD(detections, size): - h, w = size - bboxes = [] - detections = detections.reshape(-1, 7) - for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections: - if confidence >= 0.5: - x = int(xmin * w) - y = int(ymin * h) - width = int(xmax * w - x) - height = int(ymax * h - y) - bboxes.append((x, y, width, height)) - - return bboxes - - net.setInput(blob) - dnn_detections = net.forward() - dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2]) - - # OpenCV G-API - g_in = cv.GMat() - inputs = cv.GInferInputs() - inputs.setInput('data', g_in) - - g_sz = cv.gapi.streaming.size(g_in) - outputs = cv.gapi.infer("net", inputs) - detections = outputs.at("detection_out") - bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False) - - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes)) - pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) - - gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.compile_args(cv.gapi.networks(pp))) - - gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)), - args=cv.compile_args(cv.gapi.networks(pp))) - - # Comparison - self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(), - np.array(gapi_boxes).flatten(), - cv.NORM_INF)) - - - def test_person_detection_retail_0013(self): - # NB: Check IE - if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE): - return - - root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013' - model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) - img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')]) - device_id = 'CPU' - img = cv.resize(cv.imread(img_path), (544, 320)) - - # OpenCV DNN - net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path) - net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE) - net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU) - - blob = cv.dnn.blobFromImage(img) - - def parseSSD(detections, size): - h, w = size - bboxes = [] - detections = detections.reshape(-1, 7) - for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections: - if confidence >= 0.5: - x = int(xmin * w) - y = int(ymin * h) - width = int(xmax * w - x) - height = int(ymax * h - y) - bboxes.append((x, y, width, height)) - - return bboxes - - net.setInput(blob) - dnn_detections = net.forward() - dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2]) - - # OpenCV G-API - g_in = cv.GMat() - inputs = cv.GInferInputs() - inputs.setInput('data', g_in) - - g_sz = cv.gapi.streaming.size(g_in) - outputs = cv.gapi.infer("net", inputs) - detections = outputs.at("detection_out") - bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False) - - comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes)) - pp = cv.gapi.ie.params("net", model_path, weights_path, device_id) - - gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)), - args=cv.compile_args(cv.gapi.networks(pp))) - - # Comparison - self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(), - np.array(gapi_boxes).flatten(), - cv.NORM_INF)) + pass if __name__ == '__main__': diff --git a/modules/gapi/misc/python/test/test_gapi_render.py b/modules/gapi/misc/python/test/test_gapi_render.py new file mode 100644 index 000000000000..70601a72e57d --- /dev/null +++ b/modules/gapi/misc/python/test/test_gapi_render.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +import numpy as np +import cv2 as cv +import os +import sys +import unittest + +from tests_common import NewOpenCVTests + +try: + + if sys.version_info[:2] < (3, 0): + raise unittest.SkipTest('Python 2.x is not supported') + + # FIXME: FText isn't supported yet. + class gapi_render_test(NewOpenCVTests): + def __init__(self, *args): + super().__init__(*args) + + self.size = (300, 300, 3) + + # Rect + self.rect = (30, 30, 50, 50) + self.rcolor = (0, 255, 0) + self.rlt = cv.LINE_4 + self.rthick = 2 + self.rshift = 3 + + # Text + self.text = 'Hello, world!' + self.org = (100, 100) + self.ff = cv.FONT_HERSHEY_SIMPLEX + self.fs = 1.0 + self.tthick = 2 + self.tlt = cv.LINE_8 + self.tcolor = (255, 255, 255) + self.blo = False + + # Circle + self.center = (200, 200) + self.radius = 200 + self.ccolor = (255, 255, 0) + self.cthick = 2 + self.clt = cv.LINE_4 + self.cshift = 1 + + # Line + self.pt1 = (50, 50) + self.pt2 = (200, 200) + self.lcolor = (0, 255, 128) + self.lthick = 5 + self.llt = cv.LINE_8 + self.lshift = 2 + + # Poly + self.pts = [(50, 100), (100, 200), (25, 250)] + self.pcolor = (0, 0, 255) + self.pthick = 3 + self.plt = cv.LINE_4 + self.pshift = 1 + + # Image + self.iorg = (150, 150) + img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')]) + self.img = cv.resize(cv.imread(img_path), (50, 50)) + self.alpha = np.full(self.img.shape[:2], 0.8, dtype=np.float32) + + # Mosaic + self.mos = (100, 100, 100, 100) + self.cell_sz = 25 + self.decim = 0 + + # Render primitives + self.prims = [cv.gapi.wip.draw.Rect(self.rect, self.rcolor, self.rthick, self.rlt, self.rshift), + cv.gapi.wip.draw.Text(self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo), + cv.gapi.wip.draw.Circle(self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift), + cv.gapi.wip.draw.Line(self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift), + cv.gapi.wip.draw.Mosaic(self.mos, self.cell_sz, self.decim), + cv.gapi.wip.draw.Image(self.iorg, self.img, self.alpha), + cv.gapi.wip.draw.Poly(self.pts, self.pcolor, self.pthick, self.plt, self.pshift)] + + def cvt_nv12_to_yuv(self, y, uv): + h,w,_ = uv.shape + upsample_uv = cv.resize(uv, (h * 2, w * 2)) + return cv.merge([y, upsample_uv]) + + def cvt_yuv_to_nv12(self, yuv, y_out, uv_out): + chs = cv.split(yuv, [y_out, None, None]) + uv = cv.merge([chs[1], chs[2]]) + uv_out = cv.resize(uv, (uv.shape[0] // 2, uv.shape[1] // 2), dst=uv_out) + return y_out, uv_out + + def cvt_bgr_to_yuv_color(self, bgr): + y = bgr[2] * 0.299000 + bgr[1] * 0.587000 + bgr[0] * 0.114000; + u = bgr[2] * -0.168736 + bgr[1] * -0.331264 + bgr[0] * 0.500000 + 128; + v = bgr[2] * 0.500000 + bgr[1] * -0.418688 + bgr[0] * -0.081312 + 128; + return (y, u, v) + + def blend_img(self, background, org, img, alpha): + x, y = org + h, w, _ = img.shape + roi_img = background[x:x+w, y:y+h, :] + img32f_w = cv.merge([alpha] * 3).astype(np.float32) + roi32f_w = np.full(roi_img.shape, 1.0, dtype=np.float32) + roi32f_w -= img32f_w + img32f = (img / 255).astype(np.float32) + roi32f = (roi_img / 255).astype(np.float32) + cv.multiply(img32f, img32f_w, dst=img32f) + cv.multiply(roi32f, roi32f_w, dst=roi32f) + roi32f += img32f + roi_img[...] = np.round(roi32f * 255) + + # This is quite naive implementations used as a simple reference + # doesn't consider corner cases. + def draw_mosaic(self, img, mos, cell_sz, decim): + x,y,w,h = mos + mosaic_area = img[x:x+w, y:y+h, :] + for i in range(0, mosaic_area.shape[0], cell_sz): + for j in range(0, mosaic_area.shape[1], cell_sz): + cell_roi = mosaic_area[j:j+cell_sz, i:i+cell_sz, :] + s0, s1, s2 = cv.mean(cell_roi)[:3] + mosaic_area[j:j+cell_sz, i:i+cell_sz] = (round(s0), round(s1), round(s2)) + + def render_primitives_bgr_ref(self, img): + cv.rectangle(img, self.rect, self.rcolor, self.rthick, self.rlt, self.rshift) + cv.putText(img, self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo) + cv.circle(img, self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift) + cv.line(img, self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift) + cv.fillPoly(img, np.expand_dims(np.array([self.pts]), axis=0), self.pcolor, self.plt, self.pshift) + self.draw_mosaic(img, self.mos, self.cell_sz, self.decim) + self.blend_img(img, self.iorg, self.img, self.alpha) + + def render_primitives_nv12_ref(self, y_plane, uv_plane): + yuv = self.cvt_nv12_to_yuv(y_plane, uv_plane) + cv.rectangle(yuv, self.rect, self.cvt_bgr_to_yuv_color(self.rcolor), self.rthick, self.rlt, self.rshift) + cv.putText(yuv, self.text, self.org, self.ff, self.fs, self.cvt_bgr_to_yuv_color(self.tcolor), self.tthick, self.tlt, self.blo) + cv.circle(yuv, self.center, self.radius, self.cvt_bgr_to_yuv_color(self.ccolor), self.cthick, self.clt, self.cshift) + cv.line(yuv, self.pt1, self.pt2, self.cvt_bgr_to_yuv_color(self.lcolor), self.lthick, self.llt, self.lshift) + cv.fillPoly(yuv, np.expand_dims(np.array([self.pts]), axis=0), self.cvt_bgr_to_yuv_color(self.pcolor), self.plt, self.pshift) + self.draw_mosaic(yuv, self.mos, self.cell_sz, self.decim) + self.blend_img(yuv, self.iorg, cv.cvtColor(self.img, cv.COLOR_BGR2YUV), self.alpha) + self.cvt_yuv_to_nv12(yuv, y_plane, uv_plane) + + def test_render_primitives_on_bgr_graph(self): + expected = np.zeros(self.size, dtype=np.uint8) + actual = np.array(expected, copy=True) + + # OpenCV + self.render_primitives_bgr_ref(expected) + + # G-API + g_in = cv.GMat() + g_prims = cv.GArray.Prim() + g_out = cv.gapi.wip.draw.render3ch(g_in, g_prims) + + + comp = cv.GComputation(cv.GIn(g_in, g_prims), cv.GOut(g_out)) + actual = comp.apply(cv.gin(actual, self.prims)) + + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) + + def test_render_primitives_on_bgr_function(self): + expected = np.zeros(self.size, dtype=np.uint8) + actual = np.array(expected, copy=True) + + # OpenCV + self.render_primitives_bgr_ref(expected) + + # G-API + cv.gapi.wip.draw.render(actual, self.prims) + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) + + def test_render_primitives_on_nv12_graph(self): + y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8) + uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8) + + y_actual = np.array(y_expected, copy=True) + uv_actual = np.array(uv_expected, copy=True) + + # OpenCV + self.render_primitives_nv12_ref(y_expected, uv_expected) + + # G-API + g_y = cv.GMat() + g_uv = cv.GMat() + g_prims = cv.GArray.Prim() + g_out_y, g_out_uv = cv.gapi.wip.draw.renderNV12(g_y, g_uv, g_prims) + + comp = cv.GComputation(cv.GIn(g_y, g_uv, g_prims), cv.GOut(g_out_y, g_out_uv)) + y_actual, uv_actual = comp.apply(cv.gin(y_actual, uv_actual, self.prims)) + + self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF)) + self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF)) + + def test_render_primitives_on_nv12_function(self): + y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8) + uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8) + + y_actual = np.array(y_expected, copy=True) + uv_actual = np.array(uv_expected, copy=True) + + # OpenCV + self.render_primitives_nv12_ref(y_expected, uv_expected) + + # G-API + cv.gapi.wip.draw.render(y_actual, uv_actual, self.prims) + + self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF)) + self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF)) + + +except unittest.SkipTest as e: + + message = str(e) + + class TestSkip(unittest.TestCase): + def setUp(self): + self.skipTest('Skip tests: ' + message) + + def test_skip(): + pass + + pass + +if __name__ == '__main__': + NewOpenCVTests.bootstrap() diff --git a/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py b/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py index 2f921901db7a..a10d63f09ef2 100644 --- a/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py +++ b/modules/gapi/misc/python/test/test_gapi_sample_pipelines.py @@ -225,7 +225,7 @@ def test_custom_op_add(self): comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out)) pkg = cv.gapi.kernels(GAddImpl) - actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.gapi.compile_args(pkg)) self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) @@ -245,7 +245,7 @@ def test_custom_op_split3(self): comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ch1, g_ch2, g_ch3)) pkg = cv.gapi.kernels(GSplit3Impl) - ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg)) + ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg)) self.assertEqual(0.0, cv.norm(in_ch1, ch1, cv.NORM_INF)) self.assertEqual(0.0, cv.norm(in_ch2, ch2, cv.NORM_INF)) @@ -266,7 +266,7 @@ def test_custom_op_mean(self): comp = cv.GComputation(g_in, g_out) pkg = cv.gapi.kernels(GMeanImpl) - actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg)) # Comparison self.assertEqual(expected, actual) @@ -287,7 +287,7 @@ def test_custom_op_addC(self): comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(g_out)) pkg = cv.gapi.kernels(GAddCImpl) - actual = comp.apply(cv.gin(in_mat, sc), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(in_mat, sc), args=cv.gapi.compile_args(pkg)) self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) @@ -305,7 +305,7 @@ def test_custom_op_size(self): comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_sz)) pkg = cv.gapi.kernels(GSizeImpl) - actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg)) self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) @@ -322,7 +322,7 @@ def test_custom_op_sizeR(self): comp = cv.GComputation(cv.GIn(g_r), cv.GOut(g_sz)) pkg = cv.gapi.kernels(GSizeRImpl) - actual = comp.apply(cv.gin(roi), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(roi), args=cv.gapi.compile_args(pkg)) # cv.norm works with tuples ? self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) @@ -340,7 +340,7 @@ def test_custom_op_boundingRect(self): comp = cv.GComputation(cv.GIn(g_pts), cv.GOut(g_br)) pkg = cv.gapi.kernels(GBoundingRectImpl) - actual = comp.apply(cv.gin(points), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg)) # cv.norm works with tuples ? self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) @@ -371,7 +371,7 @@ def test_custom_op_goodFeaturesToTrack(self): comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) pkg = cv.gapi.kernels(GGoodFeaturesImpl) - actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg)) + actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg)) # NB: OpenCV & G-API have different output types. # OpenCV - numpy array with shape (num_points, 1, 2) @@ -453,10 +453,10 @@ def run(arr): g_in = cv.GArray.Int() comp = cv.GComputation(cv.GIn(g_in), cv.GOut(GSum.on(g_in))) - s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.compile_args(cv.gapi.kernels(GSumImpl))) + s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl))) self.assertEqual(10, s) - s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.compile_args(cv.gapi.kernels(GSumImpl))) + s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl))) self.assertEqual(18, s) self.assertEqual(18, GSumImpl.last_result) @@ -488,13 +488,13 @@ def run(table, key): 'tuple': (42, 42) } - out = comp.apply(cv.gin(table, 'int'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl))) + out = comp.apply(cv.gin(table, 'int'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl))) self.assertEqual(42, out) - out = comp.apply(cv.gin(table, 'str'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl))) + out = comp.apply(cv.gin(table, 'str'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl))) self.assertEqual('hello, world!', out) - out = comp.apply(cv.gin(table, 'tuple'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl))) + out = comp.apply(cv.gin(table, 'tuple'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl))) self.assertEqual((42, 42), out) @@ -521,7 +521,7 @@ def run(arr0, arr1): arr1 = [3, 'str'] out = comp.apply(cv.gin(arr0, arr1), - args=cv.compile_args(cv.gapi.kernels(GConcatImpl))) + args=cv.gapi.compile_args(cv.gapi.kernels(GConcatImpl))) self.assertEqual(arr0 + arr1, out) @@ -550,7 +550,7 @@ def run(img0, img1): img1 = np.array([1, 2, 3]) with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1), - args=cv.compile_args( + args=cv.gapi.compile_args( cv.gapi.kernels(GAddImpl))) @@ -577,7 +577,7 @@ def run(img0, img1): img1 = np.array([1, 2, 3]) with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1), - args=cv.compile_args( + args=cv.gapi.compile_args( cv.gapi.kernels(GAddImpl))) @@ -607,7 +607,7 @@ def run(img0, img1): # FIXME: Cause Bad variant access. # Need to provide more descriptive error messsage. with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1), - args=cv.compile_args( + args=cv.gapi.compile_args( cv.gapi.kernels(GAddImpl))) def test_pipeline_with_custom_kernels(self): @@ -657,7 +657,7 @@ def run(img, order): g_mean = cv.gapi.mean(g_transposed) comp = cv.GComputation(cv.GIn(g_bgr), cv.GOut(g_mean)) - actual = comp.apply(cv.gin(img), args=cv.compile_args( + actual = comp.apply(cv.gin(img), args=cv.gapi.compile_args( cv.gapi.kernels(GResizeImpl, GTransposeImpl))) self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) diff --git a/modules/gapi/misc/python/test/test_gapi_streaming.py b/modules/gapi/misc/python/test/test_gapi_streaming.py index 5356abc76afd..7ede1b5cf38d 100644 --- a/modules/gapi/misc/python/test/test_gapi_streaming.py +++ b/modules/gapi/misc/python/test/test_gapi_streaming.py @@ -3,201 +3,323 @@ import numpy as np import cv2 as cv import os +import sys +import unittest +import time from tests_common import NewOpenCVTests -class test_gapi_streaming(NewOpenCVTests): - def test_image_input(self): - sz = (1280, 720) - in_mat = np.random.randint(0, 100, sz).astype(np.uint8) +try: + if sys.version_info[:2] < (3, 0): + raise unittest.SkipTest('Python 2.x is not supported') - # OpenCV - expected = cv.medianBlur(in_mat, 3) - # G-API - g_in = cv.GMat() - g_out = cv.gapi.medianBlur(g_in, 3) - c = cv.GComputation(g_in, g_out) - ccomp = c.compileStreaming(cv.descr_of(in_mat)) - ccomp.setSource(cv.gin(in_mat)) - ccomp.start() + @cv.gapi.op('custom.delay', in_types=[cv.GMat], out_types=[cv.GMat]) + class GDelay: + """Delay for 10 ms.""" - _, actual = ccomp.pull() + @staticmethod + def outMeta(desc): + return desc - # Assert - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) + @cv.gapi.kernel(GDelay) + class GDelayImpl: + """Implementation for GDelay operation.""" - def test_video_input(self): - ksize = 3 - path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) + @staticmethod + def run(img): + time.sleep(0.01) + return img - # OpenCV - cap = cv.VideoCapture(path) - # G-API - g_in = cv.GMat() - g_out = cv.gapi.medianBlur(g_in, ksize) - c = cv.GComputation(g_in, g_out) + class test_gapi_streaming(NewOpenCVTests): - ccomp = c.compileStreaming() - source = cv.gapi.wip.make_capture_src(path) - ccomp.setSource(source) - ccomp.start() + def test_image_input(self): + sz = (1280, 720) + in_mat = np.random.randint(0, 100, sz).astype(np.uint8) - # Assert - max_num_frames = 10 - proc_num_frames = 0 - while cap.isOpened(): - has_expected, expected = cap.read() - has_actual, actual = ccomp.pull() + # OpenCV + expected = cv.medianBlur(in_mat, 3) + + # G-API + g_in = cv.GMat() + g_out = cv.gapi.medianBlur(g_in, 3) + c = cv.GComputation(g_in, g_out) + ccomp = c.compileStreaming(cv.gapi.descr_of(in_mat)) + ccomp.setSource(cv.gin(in_mat)) + ccomp.start() - self.assertEqual(has_expected, has_actual) + _, actual = ccomp.pull() + + # Assert + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) - if not has_actual: - break - self.assertEqual(0.0, cv.norm(cv.medianBlur(expected, ksize), actual, cv.NORM_INF)) + def test_video_input(self): + ksize = 3 + path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) - proc_num_frames += 1 - if proc_num_frames == max_num_frames: - break; + # OpenCV + cap = cv.VideoCapture(path) + # G-API + g_in = cv.GMat() + g_out = cv.gapi.medianBlur(g_in, ksize) + c = cv.GComputation(g_in, g_out) - def test_video_split3(self): - path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) + ccomp = c.compileStreaming() + source = cv.gapi.wip.make_capture_src(path) + ccomp.setSource(cv.gin(source)) + ccomp.start() - # OpenCV - cap = cv.VideoCapture(path) + # Assert + max_num_frames = 10 + proc_num_frames = 0 + while cap.isOpened(): + has_expected, expected = cap.read() + has_actual, actual = ccomp.pull() - # G-API - g_in = cv.GMat() - b, g, r = cv.gapi.split3(g_in) - c = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r)) + self.assertEqual(has_expected, has_actual) - ccomp = c.compileStreaming() - source = cv.gapi.wip.make_capture_src(path) - ccomp.setSource(source) - ccomp.start() + if not has_actual: + break - # Assert - max_num_frames = 10 - proc_num_frames = 0 - while cap.isOpened(): - has_expected, frame = cap.read() - has_actual, actual = ccomp.pull() + self.assertEqual(0.0, cv.norm(cv.medianBlur(expected, ksize), actual, cv.NORM_INF)) - self.assertEqual(has_expected, has_actual) + proc_num_frames += 1 + if proc_num_frames == max_num_frames: + break - if not has_actual: - break - expected = cv.split(frame) - for e, a in zip(expected, actual): - self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF)) + def test_video_split3(self): + path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) - proc_num_frames += 1 - if proc_num_frames == max_num_frames: - break; + # OpenCV + cap = cv.VideoCapture(path) + # G-API + g_in = cv.GMat() + b, g, r = cv.gapi.split3(g_in) + c = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r)) - def test_video_add(self): - sz = (576, 768, 3) - in_mat = np.random.randint(0, 100, sz).astype(np.uint8) + ccomp = c.compileStreaming() + source = cv.gapi.wip.make_capture_src(path) + ccomp.setSource(cv.gin(source)) + ccomp.start() - path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) + # Assert + max_num_frames = 10 + proc_num_frames = 0 + while cap.isOpened(): + has_expected, frame = cap.read() + has_actual, actual = ccomp.pull() - # OpenCV - cap = cv.VideoCapture(path) + self.assertEqual(has_expected, has_actual) - # G-API - g_in1 = cv.GMat() - g_in2 = cv.GMat() - out = cv.gapi.add(g_in1, g_in2) - c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(out)) + if not has_actual: + break - ccomp = c.compileStreaming() - source = cv.gapi.wip.make_capture_src(path) - ccomp.setSource(cv.gin(source, in_mat)) - ccomp.start() + expected = cv.split(frame) + for e, a in zip(expected, actual): + self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF)) - # Assert - max_num_frames = 10 - proc_num_frames = 0 - while cap.isOpened(): - has_expected, frame = cap.read() - has_actual, actual = ccomp.pull() + proc_num_frames += 1 + if proc_num_frames == max_num_frames: + break - self.assertEqual(has_expected, has_actual) - if not has_actual: - break + def test_video_add(self): + sz = (576, 768, 3) + in_mat = np.random.randint(0, 100, sz).astype(np.uint8) - expected = cv.add(frame, in_mat) - self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) + path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) - proc_num_frames += 1 - if proc_num_frames == max_num_frames: - break; + # OpenCV + cap = cv.VideoCapture(path) + # G-API + g_in1 = cv.GMat() + g_in2 = cv.GMat() + out = cv.gapi.add(g_in1, g_in2) + c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(out)) - def test_video_good_features_to_track(self): - path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) + ccomp = c.compileStreaming() + source = cv.gapi.wip.make_capture_src(path) + ccomp.setSource(cv.gin(source, in_mat)) + ccomp.start() - # NB: goodFeaturesToTrack configuration - max_corners = 50 - quality_lvl = 0.01 - min_distance = 10 - block_sz = 3 - use_harris_detector = True - k = 0.04 - mask = None + # Assert + max_num_frames = 10 + proc_num_frames = 0 + while cap.isOpened(): + has_expected, frame = cap.read() + has_actual, actual = ccomp.pull() - # OpenCV - cap = cv.VideoCapture(path) + self.assertEqual(has_expected, has_actual) - # G-API - g_in = cv.GMat() - g_gray = cv.gapi.RGB2Gray(g_in) - g_out = cv.gapi.goodFeaturesToTrack(g_gray, max_corners, quality_lvl, - min_distance, mask, block_sz, use_harris_detector, k) + if not has_actual: + break - c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) + expected = cv.add(frame, in_mat) + self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF)) - ccomp = c.compileStreaming() - source = cv.gapi.wip.make_capture_src(path) - ccomp.setSource(source) - ccomp.start() + proc_num_frames += 1 + if proc_num_frames == max_num_frames: + break - # Assert - max_num_frames = 10 - proc_num_frames = 0 - while cap.isOpened(): - has_expected, frame = cap.read() - has_actual, actual = ccomp.pull() - self.assertEqual(has_expected, has_actual) + def test_video_good_features_to_track(self): + path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) - if not has_actual: - break + # NB: goodFeaturesToTrack configuration + max_corners = 50 + quality_lvl = 0.01 + min_distance = 10 + block_sz = 3 + use_harris_detector = True + k = 0.04 + mask = None # OpenCV - frame = cv.cvtColor(frame, cv.COLOR_RGB2GRAY) - expected = cv.goodFeaturesToTrack(frame, max_corners, quality_lvl, - min_distance, mask=mask, - blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k) - for e, a in zip(expected, actual): - # NB: OpenCV & G-API have different output shapes: - # OpenCV - (num_points, 1, 2) - # G-API - (num_points, 2) - self.assertEqual(0.0, cv.norm(e.flatten(), - np.array(a, np.float32).flatten(), - cv.NORM_INF)) - - proc_num_frames += 1 - if proc_num_frames == max_num_frames: - break; + cap = cv.VideoCapture(path) + + # G-API + g_in = cv.GMat() + g_gray = cv.gapi.RGB2Gray(g_in) + g_out = cv.gapi.goodFeaturesToTrack(g_gray, max_corners, quality_lvl, + min_distance, mask, block_sz, use_harris_detector, k) + + c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out)) + + ccomp = c.compileStreaming() + source = cv.gapi.wip.make_capture_src(path) + ccomp.setSource(cv.gin(source)) + ccomp.start() + + # Assert + max_num_frames = 10 + proc_num_frames = 0 + while cap.isOpened(): + has_expected, frame = cap.read() + has_actual, actual = ccomp.pull() + + self.assertEqual(has_expected, has_actual) + + if not has_actual: + break + + # OpenCV + frame = cv.cvtColor(frame, cv.COLOR_RGB2GRAY) + expected = cv.goodFeaturesToTrack(frame, max_corners, quality_lvl, + min_distance, mask=mask, + blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k) + for e, a in zip(expected, actual): + # NB: OpenCV & G-API have different output shapes: + # OpenCV - (num_points, 1, 2) + # G-API - (num_points, 2) + self.assertEqual(0.0, cv.norm(e.flatten(), + np.array(a, np.float32).flatten(), + cv.NORM_INF)) + + proc_num_frames += 1 + if proc_num_frames == max_num_frames: + break + + + def test_gapi_streaming_meta(self): + ksize = 3 + path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) + + # G-API + g_in = cv.GMat() + g_ts = cv.gapi.streaming.timestamp(g_in) + g_seqno = cv.gapi.streaming.seqNo(g_in) + g_seqid = cv.gapi.streaming.seq_id(g_in) + + c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ts, g_seqno, g_seqid)) + + ccomp = c.compileStreaming() + source = cv.gapi.wip.make_capture_src(path) + ccomp.setSource(cv.gin(source)) + ccomp.start() + + # Assert + max_num_frames = 10 + curr_frame_number = 0 + while True: + has_frame, (ts, seqno, seqid) = ccomp.pull() + + if not has_frame: + break + + self.assertEqual(curr_frame_number, seqno) + self.assertEqual(curr_frame_number, seqid) + + curr_frame_number += 1 + if curr_frame_number == max_num_frames: + break + + def test_desync(self): + path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']]) + + # G-API + g_in = cv.GMat() + g_out1 = cv.gapi.copy(g_in) + des = cv.gapi.streaming.desync(g_in) + g_out2 = GDelay.on(des) + + c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out1, g_out2)) + + kernels = cv.gapi.kernels(GDelayImpl) + ccomp = c.compileStreaming(args=cv.gapi.compile_args(kernels)) + source = cv.gapi.wip.make_capture_src(path) + ccomp.setSource(cv.gin(source)) + ccomp.start() + + # Assert + max_num_frames = 10 + proc_num_frames = 0 + + out_counter = 0 + desync_out_counter = 0 + none_counter = 0 + while True: + has_frame, (out1, out2) = ccomp.pull() + if not has_frame: + break + + if not out1 is None: + out_counter += 1 + if not out2 is None: + desync_out_counter += 1 + else: + none_counter += 1 + + proc_num_frames += 1 + if proc_num_frames == max_num_frames: + ccomp.stop() + break + + self.assertLess(0, proc_num_frames) + self.assertLess(desync_out_counter, out_counter) + self.assertLess(0, none_counter) + + +except unittest.SkipTest as e: + + message = str(e) + + class TestSkip(unittest.TestCase): + def setUp(self): + self.skipTest('Skip tests: ' + message) + + def test_skip(): + pass + + pass + if __name__ == '__main__': NewOpenCVTests.bootstrap() diff --git a/modules/gapi/misc/python/test/test_gapi_types.py b/modules/gapi/misc/python/test/test_gapi_types.py index 0f3b194a2f97..dde554f5e10a 100644 --- a/modules/gapi/misc/python/test/test_gapi_types.py +++ b/modules/gapi/misc/python/test/test_gapi_types.py @@ -3,29 +3,51 @@ import numpy as np import cv2 as cv import os +import sys +import unittest from tests_common import NewOpenCVTests -class gapi_types_test(NewOpenCVTests): - def test_garray_type(self): - types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT, - cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE , - cv.gapi.CV_RECT , cv.gapi.CV_SCALAR, cv.gapi.CV_MAT , cv.gapi.CV_GMAT] +try: - for t in types: - g_array = cv.GArrayT(t) - self.assertEqual(t, g_array.type()) + if sys.version_info[:2] < (3, 0): + raise unittest.SkipTest('Python 2.x is not supported') + class gapi_types_test(NewOpenCVTests): - def test_gopaque_type(self): - types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT, - cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE , - cv.gapi.CV_RECT] + def test_garray_type(self): + types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT, + cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE , + cv.gapi.CV_RECT , cv.gapi.CV_SCALAR, cv.gapi.CV_MAT , cv.gapi.CV_GMAT] - for t in types: - g_opaque = cv.GOpaqueT(t) - self.assertEqual(t, g_opaque.type()) + for t in types: + g_array = cv.GArrayT(t) + self.assertEqual(t, g_array.type()) + + + def test_gopaque_type(self): + types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT, + cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE , + cv.gapi.CV_RECT] + + for t in types: + g_opaque = cv.GOpaqueT(t) + self.assertEqual(t, g_opaque.type()) + + +except unittest.SkipTest as e: + + message = str(e) + + class TestSkip(unittest.TestCase): + def setUp(self): + self.skipTest('Skip tests: ' + message) + + def test_skip(): + pass + + pass if __name__ == '__main__': diff --git a/modules/gapi/perf/common/gapi_core_perf_tests.hpp b/modules/gapi/perf/common/gapi_core_perf_tests.hpp index be88e5a72131..3fd543baed32 100644 --- a/modules/gapi/perf/common/gapi_core_perf_tests.hpp +++ b/modules/gapi/perf/common/gapi_core_perf_tests.hpp @@ -79,6 +79,7 @@ namespace opencv_test cv::GCompileArgs>> {}; class KMeans3DPerfTest : public TestPerfParams> {}; + class TransposePerfTest : public TestPerfParams> {}; class ResizePerfTest : public TestPerfParams> {}; class ResizeFxFyPerfTest : public TestPerfParams> {}; class ParseSSDBLPerfTest : public TestPerfParams>, public ParserSSDTest {}; diff --git a/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp b/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp index 7fe0ec4c26b6..6dfc0b2e2f88 100644 --- a/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp +++ b/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp @@ -2036,6 +2036,42 @@ PERF_TEST_P_(KMeans3DPerfTest, TestPerformance) //------------------------------------------------------------------------------ +PERF_TEST_P_(TransposePerfTest, TestPerformance) +{ + compare_f cmpF; + cv::Size sz_in; + MatType type = -1; + cv::GCompileArgs compile_args; + std::tie(cmpF, sz_in, type, compile_args) = GetParam(); + + initMatrixRandU(type, sz_in, type, false); + + // OpenCV code /////////////////////////////////////////////////////////// + cv::transpose(in_mat1, out_mat_ocv); + + // G-API code //////////////////////////////////////////////////////////// + cv::GMat in; + auto out = cv::gapi::transpose(in); + cv::GComputation c(cv::GIn(in), cv::GOut(out)); + + // Warm-up graph engine: + c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi), std::move(compile_args)); + + TEST_CYCLE() + { + c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi)); + } + + // Comparison //////////////////////////////////////////////////////////// + { + EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv)); + } + + SANITY_CHECK_NOTHING(); +} + +//------------------------------------------------------------------------------ + PERF_TEST_P_(ResizePerfTest, TestPerformance) { compare_f cmpF = get<0>(GetParam()); diff --git a/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp b/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp index 8385169050e7..871d41792beb 100644 --- a/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp +++ b/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp @@ -311,6 +311,14 @@ INSTANTIATE_TEST_CASE_P(KMeans3DPerfTestCPU, KMeans3DPerfTest, cv::KMEANS_PP_CENTERS | cv::KMEANS_USE_INITIAL_LABELS), Values(cv::compile_args(CORE_CPU)))); +INSTANTIATE_TEST_CASE_P(TransposePerfTestCPU, TransposePerfTest, + Combine(Values(AbsExact().to_compare_f()), + Values(szSmall128, szVGA, sz720p, sz1080p), + Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::compile_args(CORE_CPU)))); + INSTANTIATE_TEST_CASE_P(ResizePerfTestCPU, ResizePerfTest, Combine(Values(AbsExact().to_compare_f()), Values(CV_8UC1, CV_16UC1, CV_16SC1), diff --git a/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp b/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp index 955799634cf6..4a38fdb27b8c 100644 --- a/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp +++ b/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp @@ -276,6 +276,14 @@ INSTANTIATE_TEST_CASE_P(ConvertToPerfTestGPU, ConvertToPerfTest, Values(0.0), Values(cv::compile_args(CORE_GPU)))); +INSTANTIATE_TEST_CASE_P(TransposePerfTestGPU, TransposePerfTest, + Combine(Values(AbsExact().to_compare_f()), + Values(szSmall128, szVGA, sz720p, sz1080p), + Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::compile_args(CORE_GPU)))); + INSTANTIATE_TEST_CASE_P(ResizePerfTestGPU, ResizePerfTest, Combine(Values(AbsSimilarPoints(2, 0.05).to_compare_f()), Values(CV_8UC1, CV_16UC1, CV_16SC1), diff --git a/modules/gapi/samples/api_ref_snippets.cpp b/modules/gapi/samples/api_ref_snippets.cpp index 9c3e73a17cfb..0abcab89b383 100644 --- a/modules/gapi/samples/api_ref_snippets.cpp +++ b/modules/gapi/samples/api_ref_snippets.cpp @@ -4,11 +4,23 @@ #include #include +#include +#include +#include + #include #include #include +static void gscalar_example() +{ + //! [gscalar_implicit] + cv::GMat a; + cv::GMat b = a + 1; + //! [gscalar_implicit] +} + static void typed_example() { const cv::Size sz(32, 32); @@ -47,6 +59,120 @@ static void typed_example() //! [Typed_Example] } +static void bind_serialization_example() +{ + // ! [bind after deserialization] + cv::GCompiled compd; + std::vector bytes; + auto graph = cv::gapi::deserialize(bytes); + auto meta = cv::gapi::deserialize(bytes); + + compd = graph.compile(std::move(meta), cv::compile_args()); + auto in_args = cv::gapi::deserialize(bytes); + auto out_args = cv::gapi::deserialize(bytes); + compd(std::move(in_args), cv::gapi::bind(out_args)); + // ! [bind after deserialization] +} + +static void bind_deserialization_example() +{ + // ! [bind before serialization] + std::vector graph_outs; + cv::GRunArgs out_args; + + for (auto &&out : graph_outs) { + out_args.emplace_back(cv::gapi::bind(out)); + } + const auto sargsout = cv::gapi::serialize(out_args); + // ! [bind before serialization] +} + +struct SimpleCustomType { + bool val; + bool operator==(const SimpleCustomType& other) const { + return val == other.val; + } +}; + +struct SimpleCustomType2 { + int val; + std::string name; + std::vector vec; + std::map mmap; + bool operator==(const SimpleCustomType2& other) const { + return val == other.val && name == other.name && + vec == other.vec && mmap == other.mmap; + } +}; + +// ! [S11N usage] +namespace cv { +namespace gapi { +namespace s11n { +namespace detail { +template<> struct S11N { + static void serialize(IOStream &os, const SimpleCustomType &p) { + os << p.val; + } + static SimpleCustomType deserialize(IIStream &is) { + SimpleCustomType p; + is >> p.val; + return p; + } +}; + +template<> struct S11N { + static void serialize(IOStream &os, const SimpleCustomType2 &p) { + os << p.val << p.name << p.vec << p.mmap; + } + static SimpleCustomType2 deserialize(IIStream &is) { + SimpleCustomType2 p; + is >> p.val >> p.name >> p.vec >> p.mmap; + return p; + } +}; +} // namespace detail +} // namespace s11n +} // namespace gapi +} // namespace cv +// ! [S11N usage] + +namespace cv { +namespace detail { +template<> struct CompileArgTag { + static const char* tag() { + return "org.opencv.test.simple_custom_type"; + } +}; + +template<> struct CompileArgTag { + static const char* tag() { + return "org.opencv.test.simple_custom_type_2"; + } +}; +} // namespace detail +} // namespace cv + +static void s11n_example() +{ + SimpleCustomType customVar1 { false }; + SimpleCustomType2 customVar2 { 1248, "World", {1280, 720, 640, 480}, + { {5, 32434142342}, {7, 34242432} } }; + + std::vector sArgs = cv::gapi::serialize( + cv::compile_args(customVar1, customVar2)); + + cv::GCompileArgs dArgs = cv::gapi::deserialize(sArgs); + + SimpleCustomType dCustomVar1 = cv::gapi::getCompileArg(dArgs).value(); + SimpleCustomType2 dCustomVar2 = cv::gapi::getCompileArg(dArgs).value(); + + (void) dCustomVar1; + (void) dCustomVar2; +} + G_TYPED_KERNEL(IAdd, , "test.custom.add") { static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; } }; @@ -116,7 +242,12 @@ int main(int argc, char *argv[]) >(); //! [kernels_snippet] - // Just call typed example with no input/output + // Just call typed example with no input/output - avoid warnings about + // unused functions typed_example(); + gscalar_example(); + bind_serialization_example(); + bind_deserialization_example(); + s11n_example(); return 0; } diff --git a/modules/gapi/samples/face_detection.cpp b/modules/gapi/samples/face_detection_mtcnn.cpp similarity index 92% rename from modules/gapi/samples/face_detection.cpp rename to modules/gapi/samples/face_detection_mtcnn.cpp index 56f3f18a1381..c437bdbba46c 100644 --- a/modules/gapi/samples/face_detection.cpp +++ b/modules/gapi/samples/face_detection_mtcnn.cpp @@ -21,18 +21,19 @@ const std::string about = "This is an OpenCV-based version of OMZ MTCNN Face Detection example"; const std::string keys = -"{ h help | | Print this help message }" -"{ input | | Path to the input video file }" -"{ mtcnnpm | mtcnn-p.xml | Path to OpenVINO MTCNN P (Proposal) detection model (.xml)}" -"{ mtcnnpd | CPU | Target device for the MTCNN P (e.g. CPU, GPU, VPU, ...) }" -"{ mtcnnrm | mtcnn-r.xml | Path to OpenVINO MTCNN R (Refinement) detection model (.xml)}" -"{ mtcnnrd | CPU | Target device for the MTCNN R (e.g. CPU, GPU, VPU, ...) }" -"{ mtcnnom | mtcnn-o.xml | Path to OpenVINO MTCNN O (Output) detection model (.xml)}" -"{ mtcnnod | CPU | Target device for the MTCNN O (e.g. CPU, GPU, VPU, ...) }" -"{ thrp | 0.6 | MTCNN P confidence threshold}" -"{ thrr | 0.7 | MTCNN R confidence threshold}" -"{ thro | 0.7 | MTCNN O confidence threshold}" -"{ half_scale | false | MTCNN P use half scale pyramid}" +"{ h help | | Print this help message }" +"{ input | | Path to the input video file }" +"{ mtcnnpm | mtcnn-p.xml | Path to OpenVINO MTCNN P (Proposal) detection model (.xml)}" +"{ mtcnnpd | CPU | Target device for the MTCNN P (e.g. CPU, GPU, VPU, ...) }" +"{ mtcnnrm | mtcnn-r.xml | Path to OpenVINO MTCNN R (Refinement) detection model (.xml)}" +"{ mtcnnrd | CPU | Target device for the MTCNN R (e.g. CPU, GPU, VPU, ...) }" +"{ mtcnnom | mtcnn-o.xml | Path to OpenVINO MTCNN O (Output) detection model (.xml)}" +"{ mtcnnod | CPU | Target device for the MTCNN O (e.g. CPU, GPU, VPU, ...) }" +"{ thrp | 0.6 | MTCNN P confidence threshold}" +"{ thrr | 0.7 | MTCNN R confidence threshold}" +"{ thro | 0.7 | MTCNN O confidence threshold}" +"{ half_scale | false | MTCNN P use half scale pyramid}" +"{ queue_capacity | 1 | Streaming executor queue capacity. Calculated automaticaly if 0}" ; namespace { @@ -304,14 +305,6 @@ G_API_OP(SwapFaces, } }; -G_API_OP(Transpose, - , - "sample.custom.mtcnn.transpose") { - static cv::GMatDesc outMeta(const cv::GMatDesc in) { - return in.withSize(cv::Size(in.size.height, in.size.width)); - } -}; - //Custom kernels implementation GAPI_OCV_KERNEL(OCVBuildFaces, BuildFaces) { static void run(const cv::Mat & in_scores, @@ -371,7 +364,8 @@ GAPI_OCV_KERNEL(OCVR_O_NetPreProcGetROIs, R_O_NetPreProcGetROIs) { for (const auto& face : in_faces) { cv::Rect tmp_rect = face.bbox.getRect(); //Compare to transposed sizes width<->height - tmp_rect &= cv::Rect(tmp_rect.x, tmp_rect.y, in_image_size.height - tmp_rect.x - 4, in_image_size.width - tmp_rect.y - 4); + tmp_rect &= cv::Rect(tmp_rect.x, tmp_rect.y, in_image_size.height - tmp_rect.x, in_image_size.width - tmp_rect.y) & + cv::Rect(0, 0, in_image_size.height, in_image_size.width); outs.push_back(tmp_rect); } } @@ -449,12 +443,6 @@ GAPI_OCV_KERNEL(OCVSwapFaces, SwapFaces) { } };// GAPI_OCV_KERNEL(SwapFaces) -GAPI_OCV_KERNEL(OCVTranspose, Transpose) { - static void run(const cv::Mat &in_mat, - cv::Mat &out_mat) { - cv::transpose(in_mat, out_mat); - } -};// GAPI_OCV_KERNEL(Transpose) } // anonymous namespace } // namespace custom @@ -495,13 +483,6 @@ static inline std::tuple run_mtcnn_p(cv::GMat &in, const std return std::make_tuple(regressions, scores); } -//Operator fot PNet network package creation in the loop -inline cv::gapi::GNetPackage& operator += (cv::gapi::GNetPackage& lhs, const cv::gapi::GNetPackage& rhs) { - lhs.networks.reserve(lhs.networks.size() + rhs.networks.size()); - lhs.networks.insert(lhs.networks.end(), rhs.networks.begin(), rhs.networks.end()); - return lhs; -} - static inline std::string get_pnet_level_name(const cv::Size &in_size) { return "MTCNNProposal_" + std::to_string(in_size.width) + "x" + std::to_string(in_size.height); } @@ -588,6 +569,7 @@ int main(int argc, char* argv[]) { const auto target_dev_o = cmd.get("mtcnnod"); const auto conf_thresh_o = cmd.get("thro"); const auto use_half_scale = cmd.get("half_scale"); + const auto streaming_queue_capacity = cmd.get("queue_capacity"); std::vector level_size; std::vector scales; @@ -618,7 +600,7 @@ int main(int argc, char* argv[]) { //The very first PNet pyramid layer to init total_faces[0] in_resized[0] = cv::gapi::resize(in_originalRGB, level_size[0]); - in_transposed[0] = custom::Transpose::on(in_resized[0]); + in_transposed[0] = cv::gapi::transpose(in_resized[0]); std::tie(regressions[0], scores[0]) = run_mtcnn_p(in_transposed[0], get_pnet_level_name(level_size[0])); cv::GArray faces0 = custom::BuildFaces::on(scores[0], regressions[0], static_cast(scales[0]), conf_thresh_p); cv::GArray final_p_faces_for_bb2squares = custom::ApplyRegression::on(faces0, true); @@ -629,7 +611,7 @@ int main(int argc, char* argv[]) { for (int i = 1; i < pyramid_levels; ++i) { in_resized[i] = cv::gapi::resize(in_originalRGB, level_size[i]); - in_transposed[i] = custom::Transpose::on(in_resized[i]); + in_transposed[i] = cv::gapi::transpose(in_resized[i]); std::tie(regressions[i], scores[i]) = run_mtcnn_p(in_transposed[i], get_pnet_level_name(level_size[i])); cv::GArray faces = custom::BuildFaces::on(scores[i], regressions[i], static_cast(scales[i]), conf_thresh_p); cv::GArray final_p_faces_for_bb2squares_i = custom::ApplyRegression::on(faces, true); @@ -644,7 +626,7 @@ int main(int argc, char* argv[]) { //Refinement part of MTCNN graph cv::GArray faces_roi_pnet = custom::R_O_NetPreProcGetROIs::on(final_faces_pnet, in_sz); cv::GArray regressionsRNet, scoresRNet; - cv::GMat in_originalRGB_transposed = custom::Transpose::on(in_originalRGB); + cv::GMat in_originalRGB_transposed = cv::gapi::transpose(in_originalRGB); std::tie(regressionsRNet, scoresRNet) = cv::gapi::infer(faces_roi_pnet, in_originalRGB_transposed); //Refinement post-processing @@ -706,9 +688,11 @@ int main(int argc, char* argv[]) { , custom::OCVRNetPostProc , custom::OCVONetPostProc , custom::OCVSwapFaces - , custom::OCVTranspose >(); - auto pipeline_mtcnn = graph_mtcnn.compileStreaming(cv::compile_args(networks_mtcnn, kernels_mtcnn)); + auto mtcnn_args = cv::compile_args(networks_mtcnn, kernels_mtcnn); + if (streaming_queue_capacity != 0) + mtcnn_args += cv::compile_args(cv::gapi::streaming::queue_capacity{ streaming_queue_capacity }); + auto pipeline_mtcnn = graph_mtcnn.compileStreaming(std::move(mtcnn_args)); std::cout << "Reading " << input_file_name << std::endl; // Input stream diff --git a/modules/gapi/samples/gaze_estimation.cpp b/modules/gapi/samples/gaze_estimation.cpp index 6396d500c1ef..96b2ebf16303 100644 --- a/modules/gapi/samples/gaze_estimation.cpp +++ b/modules/gapi/samples/gaze_estimation.cpp @@ -16,13 +16,13 @@ const std::string keys = "{ h help | | Print this help message }" "{ input | | Path to the input video file }" "{ facem | face-detection-retail-0005.xml | Path to OpenVINO face detection model (.xml) }" - "{ faced | CPU | Target device for the face detection (e.g. CPU, GPU, VPU, ...) }" + "{ faced | CPU | Target device for the face detection (e.g. CPU, GPU, ...) }" "{ landm | facial-landmarks-35-adas-0002.xml | Path to OpenVINO landmarks detector model (.xml) }" - "{ landd | CPU | Target device for the landmarks detector (e.g. CPU, GPU, VPU, ...) }" + "{ landd | CPU | Target device for the landmarks detector (e.g. CPU, GPU, ...) }" "{ headm | head-pose-estimation-adas-0001.xml | Path to OpenVINO head pose estimation model (.xml) }" - "{ headd | CPU | Target device for the head pose estimation inference (e.g. CPU, GPU, VPU, ...) }" + "{ headd | CPU | Target device for the head pose estimation inference (e.g. CPU, GPU, ...) }" "{ gazem | gaze-estimation-adas-0002.xml | Path to OpenVINO gaze vector estimaiton model (.xml) }" - "{ gazed | CPU | Target device for the gaze vector estimation inference (e.g. CPU, GPU, VPU, ...) }" + "{ gazed | CPU | Target device for the gaze vector estimation inference (e.g. CPU, GPU, ...) }" ; namespace { @@ -338,7 +338,7 @@ int main(int argc, char *argv[]) cv::GMat in; cv::GMat faces = cv::gapi::infer(in); - cv::GOpaque sz = custom::Size::on(in); // FIXME + cv::GOpaque sz = cv::gapi::streaming::size(in); cv::GArray faces_rc = custom::ParseSSD::on(faces, sz, true); cv::GArray angles_y, angles_p, angles_r; std::tie(angles_y, angles_p, angles_r) = cv::gapi::infer(faces_rc, in); diff --git a/modules/gapi/src/api/ginfer.cpp b/modules/gapi/src/api/ginfer.cpp index e3cc94041c32..9db05a43c369 100644 --- a/modules/gapi/src/api/ginfer.cpp +++ b/modules/gapi/src/api/ginfer.cpp @@ -15,6 +15,10 @@ cv::gapi::GNetPackage::GNetPackage(std::initializer_list ii) : networks(ii) { } +cv::gapi::GNetPackage::GNetPackage(std::vector nets) + : networks(nets) { +} + std::vector cv::gapi::GNetPackage::backends() const { std::unordered_set unique_set; for (const auto &nn : networks) unique_set.insert(nn.backend); diff --git a/modules/gapi/src/api/gproto.cpp b/modules/gapi/src/api/gproto.cpp index 0c7c6462eea3..9b012770caee 100644 --- a/modules/gapi/src/api/gproto.cpp +++ b/modules/gapi/src/api/gproto.cpp @@ -201,6 +201,52 @@ bool cv::can_describe(const GMetaArgs &metas, const GRunArgs &args) }); } +void cv::gimpl::proto::validate_input_meta_arg(const cv::GMetaArg& meta) +{ + switch (meta.index()) + { + case cv::GMetaArg::index_of(): + { + cv::gimpl::proto::validate_input_meta(cv::util::get(meta)); //may throw + break; + } + default: + break; + } +} + +void cv::gimpl::proto::validate_input_meta(const cv::GMatDesc& meta) +{ + if (meta.dims.empty()) + { + if (!(meta.size.height > 0 && meta.size.width > 0)) + { + cv::util::throw_error + (std::logic_error( + "Image format is invalid. Size must contain positive values" + ", got width: " + std::to_string(meta.size.width ) + + (", height: ") + std::to_string(meta.size.height))); + } + + if (!(meta.chan > 0)) + { + cv::util::throw_error + (std::logic_error( + "Image format is invalid. Channel mustn't be negative value, got channel: " + + std::to_string(meta.chan))); + } + } + + if (!(meta.depth >= 0)) + { + cv::util::throw_error + (std::logic_error( + "Image format is invalid. Depth must be positive value, got depth: " + + std::to_string(meta.depth))); + } + // All checks are ok +} + // FIXME: Is it tested for all types? // FIXME: Where does this validation happen?? void cv::validate_input_arg(const GRunArg& arg) @@ -212,13 +258,15 @@ void cv::validate_input_arg(const GRunArg& arg) case GRunArg::index_of(): { const auto desc = cv::descr_of(util::get(arg)); - GAPI_Assert(desc.size.height != 0 && desc.size.width != 0 && "incorrect dimensions of cv::UMat!"); break; + cv::gimpl::proto::validate_input_meta(desc); //may throw + break; } #endif // !defined(GAPI_STANDALONE) case GRunArg::index_of(): { const auto desc = cv::descr_of(util::get(arg)); - GAPI_Assert(desc.size.height != 0 && desc.size.width != 0 && "incorrect dimensions of Mat!"); break; + cv::gimpl::proto::validate_input_meta(desc); //may throw + break; } default: // No extra handling diff --git a/modules/gapi/src/api/gproto_priv.hpp b/modules/gapi/src/api/gproto_priv.hpp index b1d71df88176..e42afc346118 100644 --- a/modules/gapi/src/api/gproto_priv.hpp +++ b/modules/gapi/src/api/gproto_priv.hpp @@ -31,6 +31,9 @@ GProtoArg rewrap (const GArg &arg); // FIXME:: GAPI_EXPORTS because of tests only!! GAPI_EXPORTS const void* ptr (const GRunArgP &arg); +void validate_input_meta_arg(const GMetaArg& meta); +void validate_input_meta(const GMatDesc& meta); + } // proto } // gimpl } // cv diff --git a/modules/gapi/src/api/kernels_core.cpp b/modules/gapi/src/api/kernels_core.cpp index 3196b5db2e73..4485e36f273f 100644 --- a/modules/gapi/src/api/kernels_core.cpp +++ b/modules/gapi/src/api/kernels_core.cpp @@ -417,6 +417,12 @@ std::tuple,GArray,GArray> kmeans(const GArray streaming::size(const GMat& src) { return streaming::GSize::on(src); diff --git a/modules/gapi/src/api/media.cpp b/modules/gapi/src/api/media.cpp index 3c171b215ff9..884fc9e83d79 100644 --- a/modules/gapi/src/api/media.cpp +++ b/modules/gapi/src/api/media.cpp @@ -26,6 +26,11 @@ cv::MediaFrame::View cv::MediaFrame::access(Access code) const { return m->adapter->access(code); } +cv::util::any cv::MediaFrame::blobParams() const +{ + return m->adapter->blobParams(); +} + cv::MediaFrame::IAdapter* cv::MediaFrame::getAdapter() const { return m->adapter.get(); } @@ -42,5 +47,11 @@ cv::MediaFrame::View::~View() { } } +cv::util::any cv::MediaFrame::IAdapter::blobParams() const +{ + // Does nothing by default + return {}; +} + cv::MediaFrame::IAdapter::~IAdapter() { } diff --git a/modules/gapi/src/api/render_ocv.cpp b/modules/gapi/src/api/render_ocv.cpp index 5ab2e1dd07c2..f1e9be4b4893 100644 --- a/modules/gapi/src/api/render_ocv.cpp +++ b/modules/gapi/src/api/render_ocv.cpp @@ -159,7 +159,7 @@ void drawPrimitivesOCV(cv::Mat& in, { const auto& rp = cv::util::get(p); const auto color = converter.cvtColor(rp.color); - cv::rectangle(in, rp.rect, color , rp.thick); + cv::rectangle(in, rp.rect, color, rp.thick, rp.lt, rp.shift); break; } @@ -198,7 +198,7 @@ void drawPrimitivesOCV(cv::Mat& in, { const auto& cp = cv::util::get(p); const auto color = converter.cvtColor(cp.color); - cv::circle(in, cp.center, cp.radius, color, cp.thick); + cv::circle(in, cp.center, cp.radius, color, cp.thick, cp.lt, cp.shift); break; } @@ -206,7 +206,7 @@ void drawPrimitivesOCV(cv::Mat& in, { const auto& lp = cv::util::get(p); const auto color = converter.cvtColor(lp.color); - cv::line(in, lp.pt1, lp.pt2, color, lp.thick); + cv::line(in, lp.pt1, lp.pt2, color, lp.thick, lp.lt, lp.shift); break; } diff --git a/modules/gapi/src/api/s11n.cpp b/modules/gapi/src/api/s11n.cpp index d08f47fd26a7..97f5a95c42a6 100644 --- a/modules/gapi/src/api/s11n.cpp +++ b/modules/gapi/src/api/s11n.cpp @@ -65,11 +65,11 @@ std::vector cv::gapi::serialize(const std::vector& vs) // FIXME: This function should move from S11N to GRunArg-related entities. // it has nothing to do with the S11N as it is -cv::GRunArgsP cv::gapi::bind(cv::GRunArgs &results) +cv::GRunArgsP cv::gapi::bind(cv::GRunArgs &out_args) { cv::GRunArgsP outputs; - outputs.reserve(results.size()); - for (cv::GRunArg &res_obj : results) + outputs.reserve(out_args.size()); + for (cv::GRunArg &res_obj : out_args) { using T = cv::GRunArg; switch (res_obj.index()) diff --git a/modules/gapi/src/backends/common/gmetabackend.cpp b/modules/gapi/src/backends/common/gmetabackend.cpp index c535569b0cef..40e87c3ea0aa 100644 --- a/modules/gapi/src/backends/common/gmetabackend.cpp +++ b/modules/gapi/src/backends/common/gmetabackend.cpp @@ -85,6 +85,19 @@ class GGraphMetaBackendImpl final: public cv::gapi::GBackend::Priv { const std::vector&) const override { return EPtr{new GraphMetaExecutable(graph, nodes)}; } + + virtual bool controlsMerge() const override + { + return true; + } + + virtual bool allowsMerge(const cv::gimpl::GIslandModel::Graph &, + const ade::NodeHandle &, + const ade::NodeHandle &, + const ade::NodeHandle &) const override + { + return false; + } }; cv::gapi::GBackend graph_meta_backend() { diff --git a/modules/gapi/src/backends/cpu/gcpucore.cpp b/modules/gapi/src/backends/cpu/gcpucore.cpp index b0bce410f78c..1f7dfb234ff8 100644 --- a/modules/gapi/src/backends/cpu/gcpucore.cpp +++ b/modules/gapi/src/backends/cpu/gcpucore.cpp @@ -634,6 +634,15 @@ GAPI_OCV_KERNEL(GCPUKMeans3D, cv::gapi::core::GKMeans3D) } }; +GAPI_OCV_KERNEL(GCPUTranspose, cv::gapi::core::GTranspose) +{ + static void run(const cv::Mat& in, cv::Mat& out) + { + cv::transpose(in, out); + } +}; + + GAPI_OCV_KERNEL(GCPUParseSSDBL, cv::gapi::nn::parsers::GParseSSDBL) { static void run(const cv::Mat& in_ssd_result, @@ -643,7 +652,12 @@ GAPI_OCV_KERNEL(GCPUParseSSDBL, cv::gapi::nn::parsers::GParseSSDBL) std::vector& out_boxes, std::vector& out_labels) { - cv::parseSSDBL(in_ssd_result, in_size, confidence_threshold, filter_label, out_boxes, out_labels); + cv::ParseSSD(in_ssd_result, in_size, + confidence_threshold, + filter_label, + false, + false, + out_boxes, out_labels); } }; @@ -656,7 +670,13 @@ GAPI_OCV_KERNEL(GOCVParseSSD, cv::gapi::nn::parsers::GParseSSD) const bool filter_out_of_bounds, std::vector& out_boxes) { - cv::parseSSD(in_ssd_result, in_size, confidence_threshold, alignment_to_square, filter_out_of_bounds, out_boxes); + std::vector unused_labels; + cv::ParseSSD(in_ssd_result, in_size, + confidence_threshold, + -1, + alignment_to_square, + filter_out_of_bounds, + out_boxes, unused_labels); } }; @@ -774,6 +794,7 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels() , GCPUKMeansNDNoInit , GCPUKMeans2D , GCPUKMeans3D + , GCPUTranspose , GCPUParseSSDBL , GOCVParseSSD , GCPUParseYolo diff --git a/modules/gapi/src/backends/cpu/gnnparsers.cpp b/modules/gapi/src/backends/cpu/gnnparsers.cpp index a5e4bf5f856d..26de960b7f77 100644 --- a/modules/gapi/src/backends/cpu/gnnparsers.cpp +++ b/modules/gapi/src/backends/cpu/gnnparsers.cpp @@ -170,48 +170,18 @@ class SSDParser } // namespace nn } // namespace gapi -void parseSSDBL(const cv::Mat& in_ssd_result, - const cv::Size& in_size, - const float confidence_threshold, - const int filter_label, - std::vector& out_boxes, - std::vector& out_labels) -{ - cv::gapi::nn::SSDParser parser(in_ssd_result.size, in_size, in_ssd_result.ptr()); - out_boxes.clear(); - out_labels.clear(); - cv::Rect rc; - float image_id, confidence; - int label; - const size_t range = parser.getMaxProposals(); - for (size_t i = 0; i < range; ++i) - { - std::tie(rc, image_id, confidence, label) = parser.extract(i); - - if (image_id < 0.f) - { - break; // marks end-of-detections - } - - if (confidence < confidence_threshold || - (filter_label != -1 && label != filter_label)) - { - continue; // filter out object classes if filter is specified - } // and skip objects with low confidence - out_boxes.emplace_back(rc & parser.getSurface()); - out_labels.emplace_back(label); - } -} - -void parseSSD(const cv::Mat& in_ssd_result, +void ParseSSD(const cv::Mat& in_ssd_result, const cv::Size& in_size, const float confidence_threshold, + const int filter_label, const bool alignment_to_square, const bool filter_out_of_bounds, - std::vector& out_boxes) + std::vector& out_boxes, + std::vector& out_labels) { cv::gapi::nn::SSDParser parser(in_ssd_result.size, in_size, in_ssd_result.ptr()); out_boxes.clear(); + out_labels.clear(); cv::Rect rc; float image_id, confidence; int label; @@ -228,12 +198,14 @@ void parseSSD(const cv::Mat& in_ssd_result, { continue; // skip objects with low confidence } - + if((filter_label != -1) && (label != filter_label)) + { + continue; // filter out object classes if filter is specified + } if (alignment_to_square) { parser.adjustBoundingBox(rc); } - const auto clipped_rc = rc & parser.getSurface(); if (filter_out_of_bounds) { @@ -243,6 +215,7 @@ void parseSSD(const cv::Mat& in_ssd_result, } } out_boxes.emplace_back(clipped_rc); + out_labels.emplace_back(label); } } diff --git a/modules/gapi/src/backends/cpu/gnnparsers.hpp b/modules/gapi/src/backends/cpu/gnnparsers.hpp index 2ae669370569..28b6128f0c7e 100644 --- a/modules/gapi/src/backends/cpu/gnnparsers.hpp +++ b/modules/gapi/src/backends/cpu/gnnparsers.hpp @@ -11,19 +11,14 @@ namespace cv { -void parseSSDBL(const cv::Mat& in_ssd_result, - const cv::Size& in_size, - const float confidence_threshold, - const int filter_label, - std::vector& out_boxes, - std::vector& out_labels); - -void parseSSD(const cv::Mat& in_ssd_result, +void ParseSSD(const cv::Mat& in_ssd_result, const cv::Size& in_size, const float confidence_threshold, + const int filter_label, const bool alignment_to_square, const bool filter_out_of_bounds, - std::vector& out_boxes); + std::vector& out_boxes, + std::vector& out_labels); void parseYolo(const cv::Mat& in_yolo_result, const cv::Size& in_size, diff --git a/modules/gapi/src/backends/ie/giebackend.cpp b/modules/gapi/src/backends/ie/giebackend.cpp index 46b6bdbb97ab..77a6515f8530 100644 --- a/modules/gapi/src/backends/ie/giebackend.cpp +++ b/modules/gapi/src/backends/ie/giebackend.cpp @@ -222,8 +222,17 @@ struct IEUnit { IE::ExecutableNetwork this_network; cv::gimpl::ie::wrap::Plugin this_plugin; + InferenceEngine::RemoteContext::Ptr rctx = nullptr; + explicit IEUnit(const cv::gapi::ie::detail::ParamDesc &pp) : params(pp) { + InferenceEngine::ParamMap* ctx_params = + cv::util::any_cast(¶ms.context_config); + if (ctx_params != nullptr) { + auto ie_core = cv::gimpl::ie::wrap::getCore(); + rctx = ie_core.CreateContext(params.device_id, *ctx_params); + } + if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) { net = cv::gimpl::ie::wrap::readNetwork(params); inputs = net.getInputsInfo(); @@ -231,7 +240,7 @@ struct IEUnit { } else if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import) { this_plugin = cv::gimpl::ie::wrap::getPlugin(params); this_plugin.SetConfig(params.config); - this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params); + this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params, rctx); // FIXME: ICNNetwork returns InputsDataMap/OutputsDataMap, // but ExecutableNetwork returns ConstInputsDataMap/ConstOutputsDataMap inputs = cv::gimpl::ie::wrap::toInputsDataMap(this_network.GetInputsInfo()); @@ -279,7 +288,8 @@ struct IEUnit { // for loadNetwork they can be obtained by using readNetwork non_const_this->this_plugin = cv::gimpl::ie::wrap::getPlugin(params); non_const_this->this_plugin.SetConfig(params.config); - non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin, net, params); + non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin, + net, params, rctx); } return {params, this_plugin, this_network}; @@ -481,7 +491,32 @@ using GConstGIEModel = ade::ConstTypedGraph , IECallable >; +inline IE::Blob::Ptr extractRemoteBlob(IECallContext& ctx, std::size_t i) { + GAPI_Assert(ctx.inShape(i) == cv::GShape::GFRAME && + "Remote blob is supported for MediaFrame only"); + + cv::util::any any_blob_params = ctx.inFrame(i).blobParams(); + auto ie_core = cv::gimpl::ie::wrap::getCore(); + + using ParamType = std::pair; + + ParamType* blob_params = cv::util::any_cast(&any_blob_params); + if (blob_params == nullptr) { + GAPI_Assert(false && "Incorrect type of blobParams: " + "expected std::pair"); + } + + return ctx.uu.rctx->CreateBlob(blob_params->first, + blob_params->second); +} + inline IE::Blob::Ptr extractBlob(IECallContext& ctx, std::size_t i) { + if (ctx.uu.rctx != nullptr) { + return extractRemoteBlob(ctx, i); + } + switch (ctx.inShape(i)) { case cv::GShape::GFRAME: { const auto& frame = ctx.inFrame(i); @@ -1060,6 +1095,7 @@ struct InferList: public cv::detail::KernelTag { } IE::Blob::Ptr this_blob = extractBlob(*ctx, 1); + std::vector> cached_dims(ctx->uu.params.num_out); for (auto i : ade::util::iota(ctx->uu.params.num_out)) { const IE::DataPtr& ie_out = ctx->uu.outputs.at(ctx->uu.params.output_names[i]); diff --git a/modules/gapi/src/backends/ie/giebackend/giewrapper.cpp b/modules/gapi/src/backends/ie/giebackend/giewrapper.cpp index ba0632d4f0f2..d4ec806e4846 100644 --- a/modules/gapi/src/backends/ie/giebackend/giewrapper.cpp +++ b/modules/gapi/src/backends/ie/giebackend/giewrapper.cpp @@ -124,7 +124,11 @@ IE::Core giewrap::getPlugin(const GIEParam& params) { { try { +#if INF_ENGINE_RELEASE >= 2021040000 + plugin.AddExtension(std::make_shared(extlib), params.device_id); +#else plugin.AddExtension(IE::make_so_pointer(extlib), params.device_id); +#endif CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << extlib); break; } diff --git a/modules/gapi/src/backends/ie/giebackend/giewrapper.hpp b/modules/gapi/src/backends/ie/giebackend/giewrapper.hpp index 3927c802b713..7e67cb8989d6 100644 --- a/modules/gapi/src/backends/ie/giebackend/giewrapper.hpp +++ b/modules/gapi/src/backends/ie/giebackend/giewrapper.hpp @@ -13,6 +13,7 @@ #include #include +#include #include "opencv2/gapi/infer/ie.hpp" @@ -50,12 +51,29 @@ GAPI_EXPORTS IE::Core getCore(); GAPI_EXPORTS IE::Core getPlugin(const GIEParam& params); GAPI_EXPORTS inline IE::ExecutableNetwork loadNetwork( IE::Core& core, const IE::CNNNetwork& net, - const GIEParam& params) { - return core.LoadNetwork(net, params.device_id); + const GIEParam& params, + IE::RemoteContext::Ptr rctx = nullptr) { + if (rctx != nullptr) { + return core.LoadNetwork(net, rctx); + } else { + return core.LoadNetwork(net, params.device_id); + } } GAPI_EXPORTS inline IE::ExecutableNetwork importNetwork( IE::Core& core, - const GIEParam& param) { - return core.ImportNetwork(param.model_path, param.device_id, {}); + const GIEParam& params, + IE::RemoteContext::Ptr rctx = nullptr) { + if (rctx != nullptr) { + std::filebuf blobFile; + if (!blobFile.open(params.model_path, std::ios::in | std::ios::binary)) + { + blobFile.close(); + throw std::runtime_error("Could not open file"); + } + std::istream graphBlob(&blobFile); + return core.ImportNetwork(graphBlob, rctx); + } else { + return core.ImportNetwork(params.model_path, params.device_id, {}); + } } #endif // INF_ENGINE_RELEASE < 2019020000 }}}} diff --git a/modules/gapi/src/backends/ocl/goclcore.cpp b/modules/gapi/src/backends/ocl/goclcore.cpp index afe211dc7e01..d74d521953fc 100644 --- a/modules/gapi/src/backends/ocl/goclcore.cpp +++ b/modules/gapi/src/backends/ocl/goclcore.cpp @@ -522,6 +522,15 @@ GAPI_OCL_KERNEL(GOCLConvertTo, cv::gapi::core::GConvertTo) } }; + +GAPI_OCL_KERNEL(GOCLTranspose, cv::gapi::core::GTranspose) +{ + static void run(const cv::UMat& in, cv::UMat& out) + { + cv::transpose(in, out); + } +}; + cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels() { static auto pkg = cv::gapi::kernels @@ -586,6 +595,7 @@ cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels() , GOCLConcatVert , GOCLLUT , GOCLConvertTo + , GOCLTranspose >(); return pkg; } diff --git a/modules/gapi/src/compiler/gcompiler.cpp b/modules/gapi/src/compiler/gcompiler.cpp index 2f442e40bd45..7dd3c80cdfbe 100644 --- a/modules/gapi/src/compiler/gcompiler.cpp +++ b/modules/gapi/src/compiler/gcompiler.cpp @@ -343,19 +343,26 @@ void cv::gimpl::GCompiler::validateInputMeta() return false; // should never happen }; + GAPI_LOG_DEBUG(nullptr, "Total count: " << m_metas.size()); for (const auto meta_arg_idx : ade::util::indexed(ade::util::zip(m_metas, c_expr.m_ins))) { const auto &meta = std::get<0>(ade::util::value(meta_arg_idx)); const auto &proto = std::get<1>(ade::util::value(meta_arg_idx)); + const auto index = ade::util::index(meta_arg_idx); + GAPI_LOG_DEBUG(nullptr, "Process index: " << index); + + // check types validity if (!meta_matches(meta, proto)) { - const auto index = ade::util::index(meta_arg_idx); util::throw_error(std::logic_error ("GComputation object type / metadata descriptor mismatch " "(argument " + std::to_string(index) + ")")); // FIXME: report what we've got and what we've expected } + + // check value consistency + gimpl::proto::validate_input_meta_arg(meta); //may throw } // All checks are ok } diff --git a/modules/gapi/src/compiler/gcompiler.hpp b/modules/gapi/src/compiler/gcompiler.hpp index 85b05d54db2a..2712c7939411 100644 --- a/modules/gapi/src/compiler/gcompiler.hpp +++ b/modules/gapi/src/compiler/gcompiler.hpp @@ -29,7 +29,7 @@ class GAPI_EXPORTS GCompiler cv::gapi::GKernelPackage m_all_kernels; cv::gapi::GNetPackage m_all_networks; - // Patters built from transformations + // Patterns built from transformations std::vector> m_all_patterns; diff --git a/modules/gapi/src/compiler/gstreaming.cpp b/modules/gapi/src/compiler/gstreaming.cpp index 3bdc0323b5c7..e45e77042755 100644 --- a/modules/gapi/src/compiler/gstreaming.cpp +++ b/modules/gapi/src/compiler/gstreaming.cpp @@ -75,6 +75,11 @@ bool cv::GStreamingCompiled::Priv::pull(cv::GOptRunArgsP &&outs) return m_exec->pull(std::move(outs)); } +std::tuple> cv::GStreamingCompiled::Priv::pull() +{ + return m_exec->pull(); +} + bool cv::GStreamingCompiled::Priv::try_pull(cv::GRunArgsP &&outs) { return m_exec->try_pull(std::move(outs)); @@ -123,18 +128,9 @@ bool cv::GStreamingCompiled::pull(cv::GRunArgsP &&outs) return m_priv->pull(std::move(outs)); } -std::tuple cv::GStreamingCompiled::pull() +std::tuple> cv::GStreamingCompiled::pull() { - GRunArgs run_args; - GRunArgsP outs; - const auto& out_info = m_priv->outInfo(); - run_args.reserve(out_info.size()); - outs.reserve(out_info.size()); - - cv::detail::constructGraphOutputs(m_priv->outInfo(), run_args, outs); - - bool is_over = m_priv->pull(std::move(outs)); - return std::make_tuple(is_over, run_args); + return m_priv->pull(); } bool cv::GStreamingCompiled::pull(cv::GOptRunArgsP &&outs) diff --git a/modules/gapi/src/compiler/gstreaming_priv.hpp b/modules/gapi/src/compiler/gstreaming_priv.hpp index 59b19d425261..1b559ba31030 100644 --- a/modules/gapi/src/compiler/gstreaming_priv.hpp +++ b/modules/gapi/src/compiler/gstreaming_priv.hpp @@ -46,6 +46,7 @@ class GAPI_EXPORTS GStreamingCompiled::Priv void start(); bool pull(cv::GRunArgsP &&outs); bool pull(cv::GOptRunArgsP &&outs); + std::tuple> pull(); bool try_pull(cv::GRunArgsP &&outs); void stop(); diff --git a/modules/gapi/src/executor/gstreamingexecutor.cpp b/modules/gapi/src/executor/gstreamingexecutor.cpp index bb1c33860b09..27049aef6327 100644 --- a/modules/gapi/src/executor/gstreamingexecutor.cpp +++ b/modules/gapi/src/executor/gstreamingexecutor.cpp @@ -1017,6 +1017,49 @@ void check_DesyncObjectConsumedByMultipleIslands(const cv::gimpl::GIslandModel:: } // for(nodes) } +// NB: Construct GRunArgsP based on passed info and store the memory in passed cv::GRunArgs. +// Needed for python bridge, because in case python user doesn't pass output arguments to apply. +void constructOptGraphOutputs(const cv::GTypesInfo &out_info, + cv::GOptRunArgs &args, + cv::GOptRunArgsP &outs) +{ + for (auto&& info : out_info) + { + switch (info.shape) + { + case cv::GShape::GMAT: + { + args.emplace_back(cv::optional{}); + outs.emplace_back(&cv::util::get>(args.back())); + break; + } + case cv::GShape::GSCALAR: + { + args.emplace_back(cv::optional{}); + outs.emplace_back(&cv::util::get>(args.back())); + break; + } + case cv::GShape::GARRAY: + { + cv::detail::VectorRef ref; + cv::util::get(info.ctor)(ref); + args.emplace_back(cv::util::make_optional(std::move(ref))); + outs.emplace_back(wrap_opt_arg(cv::util::get>(args.back()))); + break; + } + case cv::GShape::GOPAQUE: + { + cv::detail::OpaqueRef ref; + cv::util::get(info.ctor)(ref); + args.emplace_back(cv::util::make_optional(std::move(ref))); + outs.emplace_back(wrap_opt_arg(cv::util::get>(args.back()))); + break; + } + default: + cv::util::throw_error(std::logic_error("Unsupported optional output shape for Python")); + } + } +} } // anonymous namespace class cv::gimpl::GStreamingExecutor::Synchronizer final { @@ -1126,14 +1169,17 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr && m_sink_queues .resize(proto.out_nhs.size(), nullptr); m_sink_sync .resize(proto.out_nhs.size(), -1); - // Very rough estimation to limit internal queue sizes. + // Very rough estimation to limit internal queue sizes if not specified by the user. // Pipeline depth is equal to number of its (pipeline) steps. - const auto queue_capacity = 3*std::count_if - (m_gim.nodes().begin(), - m_gim.nodes().end(), - [&](ade::NodeHandle nh) { - return m_gim.metadata(nh).get().k == NodeKind::ISLAND; - }); + auto has_queue_capacity = cv::gapi::getCompileArg(m_comp_args); + const auto queue_capacity = has_queue_capacity ? has_queue_capacity->capacity : + 3*std::count_if + (m_gim.nodes().begin(), + m_gim.nodes().end(), + [&](ade::NodeHandle nh) { + return m_gim.metadata(nh).get().k == NodeKind::ISLAND; + }); + GAPI_Assert(queue_capacity != 0u); auto sync_policy = cv::gimpl::getCompileArg(m_comp_args) .value_or(cv::gapi::streaming::sync_policy::dont_sync); @@ -1317,6 +1363,16 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr && // per the same input frame, so the output traffic multiplies) GAPI_Assert(m_collector_map.size() > 0u); m_out_queue.set_capacity(queue_capacity * m_collector_map.size()); + + // FIXME: The code duplicates logic of collectGraphInfo() + cv::gimpl::GModel::ConstGraph cgr(*m_orig_graph); + auto meta = cgr.metadata().get().out_nhs; + out_info.reserve(meta.size()); + + ade::util::transform(meta, std::back_inserter(out_info), [&cgr](const ade::NodeHandle& nh) { + const auto& data = cgr.metadata(nh).get(); + return cv::GTypeInfo{data.shape, data.kind, data.ctor}; + }); } cv::gimpl::GStreamingExecutor::~GStreamingExecutor() @@ -1650,6 +1706,31 @@ bool cv::gimpl::GStreamingExecutor::pull(cv::GOptRunArgsP &&outs) return true; } +std::tuple> cv::gimpl::GStreamingExecutor::pull() +{ + using RunArgs = cv::util::variant; + bool is_over = false; + + if (m_desync) { + GOptRunArgs opt_run_args; + GOptRunArgsP opt_outs; + opt_outs.reserve(out_info.size()); + opt_run_args.reserve(out_info.size()); + + constructOptGraphOutputs(out_info, opt_run_args, opt_outs); + is_over = pull(std::move(opt_outs)); + return std::make_tuple(is_over, RunArgs(opt_run_args)); + } + + GRunArgs run_args; + GRunArgsP outs; + run_args.reserve(out_info.size()); + outs.reserve(out_info.size()); + + constructGraphOutputs(out_info, run_args, outs); + is_over = pull(std::move(outs)); + return std::make_tuple(is_over, RunArgs(run_args)); +} bool cv::gimpl::GStreamingExecutor::try_pull(cv::GRunArgsP &&outs) { diff --git a/modules/gapi/src/executor/gstreamingexecutor.hpp b/modules/gapi/src/executor/gstreamingexecutor.hpp index 40b787268228..b4aadcbbaf4d 100644 --- a/modules/gapi/src/executor/gstreamingexecutor.hpp +++ b/modules/gapi/src/executor/gstreamingexecutor.hpp @@ -195,6 +195,8 @@ class GStreamingExecutor final void wait_shutdown(); + cv::GTypesInfo out_info; + public: explicit GStreamingExecutor(std::unique_ptr &&g_model, const cv::GCompileArgs &comp_args); @@ -203,6 +205,7 @@ class GStreamingExecutor final void start(); bool pull(cv::GRunArgsP &&outs); bool pull(cv::GOptRunArgsP &&outs); + std::tuple> pull(); bool try_pull(cv::GRunArgsP &&outs); void stop(); bool running() const; diff --git a/modules/gapi/test/common/gapi_core_tests.hpp b/modules/gapi/test/common/gapi_core_tests.hpp index e87828200e9b..0d8015eac09e 100644 --- a/modules/gapi/test/common/gapi_core_tests.hpp +++ b/modules/gapi/test/common/gapi_core_tests.hpp @@ -154,6 +154,8 @@ GAPI_TEST_FIXTURE(WarpAffineTest, initMatrixRandU, GAPI_TEST_FIXTURE(KMeansNDTest, initMatrixRandU, FIXTURE_API(CompareMats, int, cv::KmeansFlags), 3, cmpF, K, flags) GAPI_TEST_FIXTURE(KMeans2DTest, initNothing, FIXTURE_API(int, cv::KmeansFlags), 2, K, flags) GAPI_TEST_FIXTURE(KMeans3DTest, initNothing, FIXTURE_API(int, cv::KmeansFlags), 2, K, flags) +GAPI_TEST_FIXTURE(TransposeTest, initMatrixRandU, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_EXT_BASE_FIXTURE(ParseSSDBLTest, ParserSSDTest, initNothing, FIXTURE_API(float, int), 2, confidence_threshold, filter_label) diff --git a/modules/gapi/test/common/gapi_core_tests_inl.hpp b/modules/gapi/test/common/gapi_core_tests_inl.hpp index d4760e804e31..d9287a176c46 100644 --- a/modules/gapi/test/common/gapi_core_tests_inl.hpp +++ b/modules/gapi/test/common/gapi_core_tests_inl.hpp @@ -1403,6 +1403,23 @@ TEST_P(KMeans3DTest, AccuracyTest) kmeansTestBody(in_vector, sz, type, K, flags, getCompileArgs()); } +TEST_P(TransposeTest, Test) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::GMat in; + auto out = cv::gapi::transpose(in); + + cv::GComputation c(in, out); + c.apply(in_mat1, out_mat_gapi, getCompileArgs()); + // OpenCV code ///////////////////////////////////////////////////////////// + { + cv::transpose(in_mat1, out_mat_ocv); + } + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_TRUE(cmpF(out_mat_ocv, out_mat_gapi)); + } +} // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! ////////////////////// TEST_P(BackendOutputAllocationTest, EmptyOutput) diff --git a/modules/gapi/test/common/gapi_tests_common.hpp b/modules/gapi/test/common/gapi_tests_common.hpp index 777574964a7b..463e9949e93f 100644 --- a/modules/gapi/test/common/gapi_tests_common.hpp +++ b/modules/gapi/test/common/gapi_tests_common.hpp @@ -542,6 +542,7 @@ struct TestWithParamsSpecific : public TestWithParamsBase::value` #define GAPI_TEST_FIXTURE(Fixture, InitF, API, Number, ...) \ struct Fixture : public TestWithParams API { \ static_assert(Number == AllParams::specific_params_size, \ diff --git a/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp index 5a06671ae323..424cf1b0ad83 100644 --- a/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp +++ b/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp @@ -551,6 +551,16 @@ INSTANTIATE_TEST_CASE_P(KMeans3DInitTestCPU, KMeans3DTest, Values(cv::KMEANS_RANDOM_CENTERS | cv::KMEANS_USE_INITIAL_LABELS, cv::KMEANS_PP_CENTERS | cv::KMEANS_USE_INITIAL_LABELS))); +INSTANTIATE_TEST_CASE_P(TransposeTestCPU, TransposeTest, + Combine(Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::Size(1280, 720), + cv::Size(640, 480), + cv::Size(128, 128)), + Values(-1), + Values(CORE_CPU), + Values(AbsExact().to_compare_obj()))); // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! ////////////////////// INSTANTIATE_TEST_CASE_P(BackendOutputAllocationTestCPU, BackendOutputAllocationTest, diff --git a/modules/gapi/test/cpu/gapi_stereo_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_stereo_tests_cpu.cpp index 5a70b5faeaf0..bc4ed3fe84bb 100644 --- a/modules/gapi/test/cpu/gapi_stereo_tests_cpu.cpp +++ b/modules/gapi/test/cpu/gapi_stereo_tests_cpu.cpp @@ -26,11 +26,14 @@ INSTANTIATE_TEST_CASE_P(CPU_Tests, TestGAPIStereo, Values(STEREO_CPU), Values(cv::gapi::StereoOutputFormat::DEPTH_FLOAT16, cv::gapi::StereoOutputFormat::DEPTH_FLOAT32, - cv::gapi::StereoOutputFormat::DISPARITY_FIXED16_12_4), + cv::gapi::StereoOutputFormat::DISPARITY_FIXED16_12_4, + cv::gapi::StereoOutputFormat::DEPTH_16F, + cv::gapi::StereoOutputFormat::DEPTH_32F, + cv::gapi::StereoOutputFormat::DISPARITY_16Q_11_4), Values(16), Values(43), - Values(10.), - Values(100.), + Values(63.5), + Values(3.6), Values(AbsExact().to_compare_obj()))); } // opencv_test diff --git a/modules/gapi/test/gapi_frame_tests.cpp b/modules/gapi/test/gapi_frame_tests.cpp index ab271087dc34..5911ef9d9ab4 100644 --- a/modules/gapi/test/gapi_frame_tests.cpp +++ b/modules/gapi/test/gapi_frame_tests.cpp @@ -174,4 +174,11 @@ TEST(MediaFrame, Callback) { EXPECT_EQ(3, counter); } +TEST(MediaFrame, blobParams) { + cv::Mat bgr = cv::Mat::eye(240, 320, CV_8UC3); + cv::MediaFrame frame = cv::MediaFrame::Create(bgr); + + EXPECT_NO_THROW(frame.blobParams()); +} + } // namespace opencv_test diff --git a/modules/gapi/test/gapi_gcompiled_tests.cpp b/modules/gapi/test/gapi_gcompiled_tests.cpp index 7951a4c2ff81..25d02fb8e9ea 100644 --- a/modules/gapi/test/gapi_gcompiled_tests.cpp +++ b/modules/gapi/test/gapi_gcompiled_tests.cpp @@ -37,6 +37,31 @@ namespace { } }; + + struct GCompiledValidateMetaEmpty: public ::testing::Test + { + cv::GMat in; + cv::GScalar scale; + cv::GComputation m_ucc; + + G_API_OP(GReturn42, (cv::GMat)>, "org.opencv.test.return_42") + { + static GOpaqueDesc outMeta(cv::GMatDesc /* in */) { return cv::empty_gopaque_desc(); } + }; + + GAPI_OCV_KERNEL(GOCVReturn42, GReturn42) + { + static void run(const cv::Mat &/* in */, int &out) + { + out = 42; + } + }; + + GCompiledValidateMetaEmpty() : m_ucc(cv::GIn(in), + cv::GOut(GReturn42::on(in))) + { + } + }; } // anonymous namespace TEST_F(GCompiledValidateMetaTyped, ValidMeta) @@ -170,4 +195,38 @@ TEST_F(GCompiledValidateMetaUntyped, InvalidMetaNumber) EXPECT_THROW(f(cv::gin(in1, sc), cv::gout(out1, out2)), std::logic_error); } +TEST_F(GCompiledValidateMetaEmpty, InvalidMatMetaCompile) +{ + EXPECT_THROW(m_ucc.compile(cv::empty_gmat_desc(), + cv::empty_scalar_desc()), + std::logic_error); +} + +TEST_F(GCompiledValidateMetaEmpty, InvalidMatMetaApply) +{ + cv::Mat emptyIn; + int out {}; + const auto pkg = cv::gapi::kernels(); + + EXPECT_THROW(m_ucc.apply(cv::gin(emptyIn), cv::gout(out), cv::compile_args(pkg)), + std::logic_error); +} + +TEST_F(GCompiledValidateMetaEmpty, ValidInvalidMatMetasApply) +{ + int out {}; + const auto pkg = cv::gapi::kernels(); + + cv::Mat nonEmptyMat = cv::Mat::eye(cv::Size(64,32), CV_8UC1); + m_ucc.apply(cv::gin(nonEmptyMat), cv::gout(out), cv::compile_args(pkg)); + EXPECT_EQ(out, 42); + + cv::Mat emptyIn; + EXPECT_THROW(m_ucc.apply(cv::gin(emptyIn), cv::gout(out), cv::compile_args(pkg)), + std::logic_error); + + out = 0; + m_ucc.apply(cv::gin(nonEmptyMat), cv::gout(out), cv::compile_args(pkg)); + EXPECT_EQ(out, 42); +} } // namespace opencv_test diff --git a/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp b/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp index 4e5efe6d3ff5..2cc859c5391b 100644 --- a/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp +++ b/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp @@ -402,6 +402,16 @@ INSTANTIATE_TEST_CASE_P(ConcatVertTestGPU, ConcatVertTest, Values(-1), Values(CORE_GPU))); +INSTANTIATE_TEST_CASE_P(TransposeTestGPU, TransposeTest, + Combine(Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::Size(1280, 720), + cv::Size(640, 480), + cv::Size(128, 128)), + Values(-1), + Values(CORE_GPU), + Values(AbsExact().to_compare_obj()))); // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! ////////////////////// INSTANTIATE_TEST_CASE_P(BackendOutputAllocationTestGPU, BackendOutputAllocationTest, diff --git a/modules/gapi/test/infer/gapi_infer_ie_test.cpp b/modules/gapi/test/infer/gapi_infer_ie_test.cpp index 4ea33f7713d0..e33f165ae165 100644 --- a/modules/gapi/test/infer/gapi_infer_ie_test.cpp +++ b/modules/gapi/test/infer/gapi_infer_ie_test.cpp @@ -56,6 +56,15 @@ class TestMediaBGR final: public cv::MediaFrame::IAdapter { cv::MediaFrame::View::Strides ss = { m_mat.step, 0u, 0u, 0u }; return cv::MediaFrame::View(std::move(pp), std::move(ss), Cb{m_cb}); } + cv::util::any blobParams() const override { + return std::make_pair({IE::Precision::U8, + {1, 3, 300, 300}, + IE::Layout::NCHW}, + {{"HELLO", 42}, + {"COLOR_FORMAT", + InferenceEngine::ColorFormat::NV12}}); + } }; class TestMediaNV12 final: public cv::MediaFrame::IAdapter { @@ -2028,6 +2037,21 @@ TEST_F(ROIList, CallInferMultipleTimes) validate(); } +TEST(IEFrameAdapter, blobParams) +{ + cv::Mat bgr = cv::Mat::eye(240, 320, CV_8UC3); + cv::MediaFrame frame = cv::MediaFrame::Create(bgr); + + auto expected = std::make_pair(IE::TensorDesc{IE::Precision::U8, {1, 3, 300, 300}, + IE::Layout::NCHW}, + IE::ParamMap{{"HELLO", 42}, {"COLOR_FORMAT", + IE::ColorFormat::NV12}}); + + auto actual = cv::util::any_cast(frame.blobParams()); + + EXPECT_EQ(expected, actual); +} + } // namespace opencv_test #endif // HAVE_INF_ENGINE diff --git a/modules/gapi/test/infer/gapi_infer_onnx_test.cpp b/modules/gapi/test/infer/gapi_infer_onnx_test.cpp index ef192b9d6a96..b1bf9c935694 100644 --- a/modules/gapi/test/infer/gapi_infer_onnx_test.cpp +++ b/modules/gapi/test/infer/gapi_infer_onnx_test.cpp @@ -67,17 +67,17 @@ struct ONNXInitPath { static ONNXInitPath g_init_path; cv::Mat initMatrixRandU(const int type, const cv::Size& sz_in) { - const cv::Mat in_mat1 = cv::Mat(sz_in, type); + const cv::Mat in_mat = cv::Mat(sz_in, type); if (CV_MAT_DEPTH(type) < CV_32F) { - cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255)); + cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar::all(255)); } else { const int fscale = 256; // avoid bits near ULP, generate stable test input - cv::Mat in_mat32s(in_mat1.size(), CV_MAKE_TYPE(CV_32S, CV_MAT_CN(type))); + cv::Mat in_mat32s(in_mat.size(), CV_MAKE_TYPE(CV_32S, CV_MAT_CN(type))); cv::randu(in_mat32s, cv::Scalar::all(0), cv::Scalar::all(255 * fscale)); - in_mat32s.convertTo(in_mat1, type, 1.0f / fscale, 0); + in_mat32s.convertTo(in_mat, type, 1.0f / fscale, 0); } - return in_mat1; + return in_mat; } } // anonymous namespace namespace opencv_test @@ -319,15 +319,13 @@ class ONNXtest : public ::testing::Test { size_t num_in, num_out; std::vector out_gapi; std::vector out_onnx; - cv::Mat in_mat1; + cv::Mat in_mat; ONNXtest() { initTestDataPath(); env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "test"); memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); out_gapi.resize(1); - // FIXME: It should be an image from own (gapi) directory in opencv extra - in_mat1 = cv::imread(findDataFile("cv/dpm/cat.png")); } template @@ -463,13 +461,9 @@ class ONNXMediaFrame : public ONNXClassification { cv::Rect(cv::Point{70, 10}, cv::Size{20, 260}), cv::Rect(cv::Point{5, 15}, cv::Size{200, 160}), }; - cv::Mat m_in_y; - cv::Mat m_in_uv; - virtual void SetUp() { - cv::Size sz{640, 480}; - m_in_y = initMatrixRandU(CV_8UC1, sz); - m_in_uv = initMatrixRandU(CV_8UC2, sz / 2); - } + const cv::Size sz{640, 480}; + const cv::Mat m_in_y = initMatrixRandU(CV_8UC1, sz); + const cv::Mat m_in_uv = initMatrixRandU(CV_8UC2, sz / 2); }; class ONNXGRayScale : public ONNXtest { @@ -545,20 +539,20 @@ class ONNXYoloV3 : public ONNXWithRemap { public: std::vector ins; -private: - virtual void SetUp() { + void constructYoloInputs(const cv::Mat& src) { const int yolo_in_h = 416; const int yolo_in_w = 416; cv::Mat yolov3_input, shape, prep_mat; - cv::resize(in_mat1, yolov3_input, cv::Size(yolo_in_w, yolo_in_h)); + cv::resize(src, yolov3_input, cv::Size(yolo_in_w, yolo_in_h)); shape.create(cv::Size(2, 1), CV_32F); float* ptr = shape.ptr(); - ptr[0] = in_mat1.cols; - ptr[1] = in_mat1.rows; + ptr[0] = src.cols; + ptr[1] = src.rows; preprocess(yolov3_input, prep_mat); ins = {prep_mat, shape}; } +private: void preprocess(const cv::Mat& src, cv::Mat& dst) { cv::Mat cvt; src.convertTo(cvt, CV_32F, 1.f / 255.f); @@ -571,9 +565,10 @@ class ONNXYoloV3 : public ONNXWithRemap { TEST_F(ONNXClassification, Infer) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // ONNX_API code cv::Mat processed_mat; - preprocess(in_mat1, processed_mat); + preprocess(in_mat, processed_mat); infer(processed_mat, out_onnx); // G_API code G_API_NET(SqueezNet, , "squeeznet"); @@ -583,7 +578,7 @@ TEST_F(ONNXClassification, Infer) // NOTE: We have to normalize U8 tensor // so cfgMeanStd() is here auto net = cv::gapi::onnx::Params { model_path }.cfgMeanStd({ mean }, { std }); - comp.apply(cv::gin(in_mat1), + comp.apply(cv::gin(in_mat), cv::gout(out_gapi.front()), cv::compile_args(cv::gapi::networks(net))); // Validate @@ -593,9 +588,10 @@ TEST_F(ONNXClassification, Infer) TEST_F(ONNXClassification, InferTensor) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // Create tensor cv::Mat tensor; - preprocess(in_mat1, tensor); + preprocess(in_mat, tensor); // ONNX_API code infer(tensor, out_onnx); // G_API code @@ -614,10 +610,11 @@ TEST_F(ONNXClassification, InferTensor) TEST_F(ONNXClassification, InferROI) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); const auto ROI = rois.at(0); // ONNX_API code cv::Mat roi_mat; - preprocess(in_mat1(ROI), roi_mat); + preprocess(in_mat(ROI), roi_mat); infer(roi_mat, out_onnx); // G_API code G_API_NET(SqueezNet, , "squeeznet"); @@ -628,7 +625,7 @@ TEST_F(ONNXClassification, InferROI) // NOTE: We have to normalize U8 tensor // so cfgMeanStd() is here auto net = cv::gapi::onnx::Params { model_path }.cfgMeanStd({ mean }, { std }); - comp.apply(cv::gin(in_mat1, ROI), + comp.apply(cv::gin(in_mat, ROI), cv::gout(out_gapi.front()), cv::compile_args(cv::gapi::networks(net))); // Validate @@ -638,10 +635,11 @@ TEST_F(ONNXClassification, InferROI) TEST_F(ONNXClassification, InferROIList) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // ONNX_API code for (size_t i = 0; i < rois.size(); ++i) { cv::Mat roi_mat; - preprocess(in_mat1(rois[i]), roi_mat); + preprocess(in_mat(rois[i]), roi_mat); infer(roi_mat, out_onnx); } // G_API code @@ -653,7 +651,7 @@ TEST_F(ONNXClassification, InferROIList) // NOTE: We have to normalize U8 tensor // so cfgMeanStd() is here auto net = cv::gapi::onnx::Params { model_path }.cfgMeanStd({ mean }, { std }); - comp.apply(cv::gin(in_mat1, rois), + comp.apply(cv::gin(in_mat, rois), cv::gout(out_gapi), cv::compile_args(cv::gapi::networks(net))); // Validate @@ -663,10 +661,11 @@ TEST_F(ONNXClassification, InferROIList) TEST_F(ONNXClassification, Infer2ROIList) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // ONNX_API code for (size_t i = 0; i < rois.size(); ++i) { cv::Mat roi_mat; - preprocess(in_mat1(rois[i]), roi_mat); + preprocess(in_mat(rois[i]), roi_mat); infer(roi_mat, out_onnx); } // G_API code @@ -678,7 +677,7 @@ TEST_F(ONNXClassification, Infer2ROIList) // NOTE: We have to normalize U8 tensor // so cfgMeanStd() is here auto net = cv::gapi::onnx::Params { model_path }.cfgMeanStd({ mean }, { std }); - comp.apply(cv::gin(in_mat1, rois), + comp.apply(cv::gin(in_mat, rois), cv::gout(out_gapi), cv::compile_args(cv::gapi::networks(net))); // Validate @@ -688,9 +687,10 @@ TEST_F(ONNXClassification, Infer2ROIList) TEST_F(ONNXWithRemap, InferDynamicInputTensor) { useModel("object_detection_segmentation/tiny-yolov2/model/tinyyolov2-8"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // Create tensor cv::Mat cvt, rsz, tensor; - cv::resize(in_mat1, rsz, cv::Size{416, 416}); + cv::resize(in_mat, rsz, cv::Size{416, 416}); rsz.convertTo(cvt, CV_32F, 1.f / 255.f); toCHW(cvt, tensor); tensor = tensor.reshape(1, {1, 3, 416, 416}); @@ -714,9 +714,10 @@ TEST_F(ONNXWithRemap, InferDynamicInputTensor) TEST_F(ONNXGRayScale, InferImage) { useModel("body_analysis/emotion_ferplus/model/emotion-ferplus-8"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // ONNX_API code cv::Mat prep_mat; - preprocess(in_mat1, prep_mat); + preprocess(in_mat, prep_mat); infer(prep_mat, out_onnx); // G_API code G_API_NET(EmotionNet, , "emotion-ferplus"); @@ -725,7 +726,7 @@ TEST_F(ONNXGRayScale, InferImage) cv::GComputation comp(cv::GIn(in), cv::GOut(out)); auto net = cv::gapi::onnx::Params { model_path } .cfgNormalize({ false }); // model accepts 0..255 range in FP32; - comp.apply(cv::gin(in_mat1), + comp.apply(cv::gin(in_mat), cv::gout(out_gapi.front()), cv::compile_args(cv::gapi::networks(net))); // Validate @@ -735,8 +736,9 @@ TEST_F(ONNXGRayScale, InferImage) TEST_F(ONNXWithRemap, InferMultiOutput) { useModel("object_detection_segmentation/ssd-mobilenetv1/model/ssd_mobilenet_v1_10"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // ONNX_API code - const auto prep_mat = in_mat1.reshape(1, {1, in_mat1.rows, in_mat1.cols, in_mat1.channels()}); + const auto prep_mat = in_mat.reshape(1, {1, in_mat.rows, in_mat.cols, in_mat.channels()}); infer(prep_mat, out_onnx); cv::Mat onnx_conv_out({1, 1, 200, 7}, CV_32F); remapToIESSDOut({out_onnx[3], out_onnx[0], out_onnx[2], out_onnx[1]}, onnx_conv_out); @@ -750,7 +752,7 @@ TEST_F(ONNXWithRemap, InferMultiOutput) auto net = cv::gapi::onnx::Params{ model_path } .cfgOutputLayers({"detection_output"}) .cfgPostProc({cv::GMatDesc{CV_32F, {1, 1, 200, 7}}}, remapSSDPorts); - comp.apply(cv::gin(in_mat1), + comp.apply(cv::gin(in_mat), cv::gout(out_gapi.front()), cv::compile_args(cv::gapi::networks(net))); // Validate @@ -760,12 +762,13 @@ TEST_F(ONNXWithRemap, InferMultiOutput) TEST_F(ONNXMediaFrame, InferBGR) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // ONNX_API code cv::Mat processed_mat; - preprocess(in_mat1, processed_mat); + preprocess(in_mat, processed_mat); infer(processed_mat, out_onnx); // G_API code - auto frame = MediaFrame::Create(in_mat1); + auto frame = MediaFrame::Create(in_mat); G_API_NET(SqueezNet, , "squeeznet"); cv::GFrame in; cv::GMat out = cv::gapi::infer(in); @@ -783,6 +786,7 @@ TEST_F(ONNXMediaFrame, InferBGR) TEST_F(ONNXMediaFrame, InferYUV) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); const auto frame = MediaFrame::Create(m_in_y, m_in_uv); // ONNX_API code cv::Mat pp; @@ -808,10 +812,11 @@ TEST_F(ONNXMediaFrame, InferYUV) TEST_F(ONNXMediaFrame, InferROIBGR) { useModel("classification/squeezenet/model/squeezenet1.0-9"); - auto frame = MediaFrame::Create(in_mat1); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); + auto frame = MediaFrame::Create(in_mat); // ONNX_API code cv::Mat roi_mat; - preprocess(in_mat1(rois.front()), roi_mat); + preprocess(in_mat(rois.front()), roi_mat); infer(roi_mat, out_onnx); // G_API code G_API_NET(SqueezNet, , "squeeznet"); @@ -832,6 +837,7 @@ TEST_F(ONNXMediaFrame, InferROIBGR) TEST_F(ONNXMediaFrame, InferROIYUV) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); const auto frame = MediaFrame::Create(m_in_y, m_in_uv); // ONNX_API code cv::Mat pp; @@ -858,11 +864,12 @@ TEST_F(ONNXMediaFrame, InferROIYUV) TEST_F(ONNXMediaFrame, InferListBGR) { useModel("classification/squeezenet/model/squeezenet1.0-9"); - const auto frame = MediaFrame::Create(in_mat1); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); + const auto frame = MediaFrame::Create(in_mat); // ONNX_API code for (size_t i = 0; i < rois.size(); ++i) { cv::Mat roi_mat; - preprocess(in_mat1(rois[i]), roi_mat); + preprocess(in_mat(rois[i]), roi_mat); infer(roi_mat, out_onnx); } // G_API code @@ -884,6 +891,7 @@ TEST_F(ONNXMediaFrame, InferListBGR) TEST_F(ONNXMediaFrame, InferListYUV) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); const auto frame = MediaFrame::Create(m_in_y, m_in_uv); // ONNX_API code cv::Mat pp; @@ -911,8 +919,9 @@ TEST_F(ONNXMediaFrame, InferListYUV) TEST_F(ONNXRCNN, InferWithDisabledOut) { useModel("object_detection_segmentation/faster-rcnn/model/FasterRCNN-10"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); cv::Mat pp; - preprocess(in_mat1, pp); + preprocess(in_mat, pp); // ONNX_API code infer(pp, out_onnx, {"6379", "6383"}); // G_API code @@ -937,11 +946,12 @@ TEST_F(ONNXRCNN, InferWithDisabledOut) TEST_F(ONNXMediaFrame, InferList2BGR) { useModel("classification/squeezenet/model/squeezenet1.0-9"); - const auto frame = MediaFrame::Create(in_mat1); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); + const auto frame = MediaFrame::Create(in_mat); // ONNX_API code for (size_t i = 0; i < rois.size(); ++i) { cv::Mat roi_mat; - preprocess(in_mat1(rois[i]), roi_mat); + preprocess(in_mat(rois[i]), roi_mat); infer(roi_mat, out_onnx); } // G_API code @@ -963,6 +973,7 @@ TEST_F(ONNXMediaFrame, InferList2BGR) TEST_F(ONNXMediaFrame, InferList2YUV) { useModel("classification/squeezenet/model/squeezenet1.0-9"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); const auto frame = MediaFrame::Create(m_in_y, m_in_uv); // ONNX_API code cv::Mat pp; @@ -991,6 +1002,8 @@ TEST_F(ONNXMediaFrame, InferList2YUV) TEST_F(ONNXYoloV3, InferConstInput) { useModel("object_detection_segmentation/yolov3/model/yolov3-10"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); + constructYoloInputs(in_mat); // ONNX_API code infer(ins, out_onnx); // G_API code @@ -1022,6 +1035,8 @@ TEST_F(ONNXYoloV3, InferBSConstInput) // and all input layer names are specified. // Const input has the advantage. It is expected behavior. useModel("object_detection_segmentation/yolov3/model/yolov3-10"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); + constructYoloInputs(in_mat); // Tensor with incorrect image size // is used for check case when InputLayers and constInput have same names cv::Mat bad_shape; @@ -1059,8 +1074,9 @@ TEST_F(ONNXYoloV3, InferBSConstInput) TEST_F(ONNXRCNN, ConversionInt64to32) { useModel("object_detection_segmentation/faster-rcnn/model/FasterRCNN-10"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); cv::Mat dst; - preprocess(in_mat1, dst); + preprocess(in_mat, dst); // ONNX_API code infer(dst, out_onnx); // G_API code @@ -1087,6 +1103,7 @@ TEST_F(ONNXRCNN, ConversionInt64to32) TEST_F(ONNXWithRemap, InferOutReallocation) { useModel("object_detection_segmentation/ssd-mobilenetv1/model/ssd_mobilenet_v1_10"); + in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false)); // G_API code G_API_NET(MobileNet, , "ssd_mobilenet"); auto net = cv::gapi::onnx::Params{model_path} @@ -1096,7 +1113,7 @@ TEST_F(ONNXWithRemap, InferOutReallocation) cv::GMat out1; out1 = cv::gapi::infer(in); cv::GComputation comp(cv::GIn(in), cv::GOut(out1)); - EXPECT_THROW(comp.apply(cv::gin(in_mat1), + EXPECT_THROW(comp.apply(cv::gin(in_mat), cv::gout(out_gapi[0]), cv::compile_args(cv::gapi::networks(net))), std::exception); } diff --git a/modules/gapi/test/render/gapi_render_tests_ocv.cpp b/modules/gapi/test/render/gapi_render_tests_ocv.cpp index 010df5dff75b..95f695415609 100644 --- a/modules/gapi/test/render/gapi_render_tests_ocv.cpp +++ b/modules/gapi/test/render/gapi_render_tests_ocv.cpp @@ -639,8 +639,8 @@ INSTANTIATE_TEST_CASE_P(RenderBGROCVTestRectsImpl, RenderBGROCVTestRects, Values(cv::Rect(100, 100, 200, 200)), Values(cv::Scalar(100, 50, 150)), Values(2), - Values(LINE_8), - Values(0))); + Values(LINE_8, LINE_4), + Values(0, 1))); INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects, Combine(Values(cv::Size(1280, 720)), @@ -673,8 +673,8 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestCirclesImpl, RenderNV12OCVTestCircles, Values(10), Values(cv::Scalar(100, 50, 150)), Values(2), - Values(LINE_8), - Values(0))); + Values(LINE_8, LINE_4), + Values(0, 1))); INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestCirclesImpl, RenderMFrameOCVTestCircles, Combine(Values(cv::Size(1280, 720)), diff --git a/modules/gapi/test/s11n/gapi_s11n_tests.cpp b/modules/gapi/test/s11n/gapi_s11n_tests.cpp index f4a30b394631..c2b17521d966 100644 --- a/modules/gapi/test/s11n/gapi_s11n_tests.cpp +++ b/modules/gapi/test/s11n/gapi_s11n_tests.cpp @@ -754,8 +754,6 @@ TEST_F(S11N_Basic, Test_Deserialize_CompileArgs_RandomOrder) { std::vector sArgs = cv::gapi::serialize( cv::compile_args(simpleCustomVar, simpleCustomVar2)); GCompileArgs dArgs = cv::gapi::deserialize(sArgs); diff --git a/modules/gapi/test/streaming/gapi_streaming_tests.cpp b/modules/gapi/test/streaming/gapi_streaming_tests.cpp index 064511880e3d..5386d1736f67 100644 --- a/modules/gapi/test/streaming/gapi_streaming_tests.cpp +++ b/modules/gapi/test/streaming/gapi_streaming_tests.cpp @@ -67,13 +67,24 @@ std::ostream& operator<< (std::ostream &os, const KernelPackage &e) return os; } -struct GAPI_Streaming: public ::testing::TestWithParam { - GAPI_Streaming() { initTestDataPath(); } +struct GAPI_Streaming: public ::testing::TestWithParam>> { + GAPI_Streaming() { + initTestDataPath(); + KernelPackage pkg_kind; + std::tie(pkg_kind, cap) = GetParam(); + pkg = getKernelPackage(pkg_kind); + } - cv::gapi::GKernelPackage getKernelPackage() + const cv::optional& getQueueCapacity() + { + return cap; + } + + cv::gapi::GKernelPackage getKernelPackage(KernelPackage pkg_kind) { using namespace cv::gapi; - switch (GetParam()) + switch (pkg_kind) { case KernelPackage::OCV: return cv::gapi::combine(core::cpu::kernels(), @@ -104,6 +115,18 @@ struct GAPI_Streaming: public ::testing::TestWithParam { } throw std::logic_error("Unknown package"); } + + cv::GCompileArgs getCompileArgs() { + using namespace cv::gapi; + auto args = cv::compile_args(use_only{pkg}); + if (cap) { + args += cv::compile_args(streaming::queue_capacity{cap.value()}); + } + return args; + } + + cv::gapi::GKernelPackage pkg; + cv::optional cap; }; G_API_OP(Delay, , "org.opencv.test.delay") { @@ -221,6 +244,35 @@ class NV12Source : public cv::gapi::wip::GCaptureSource { } }; +void checkPullOverload(const cv::Mat& ref, + const bool has_output, + cv::util::variant& args) { + EXPECT_TRUE(has_output); + using runArgs = cv::util::variant; + cv::Mat out_mat; + switch (args.index()) { + case runArgs::index_of(): + { + auto outputs = util::get(args); + EXPECT_EQ(1u, outputs.size()); + out_mat = cv::util::get(outputs[0]); + break; + } + case runArgs::index_of(): + { + auto outputs = util::get(args); + EXPECT_EQ(1u, outputs.size()); + auto opt_mat = cv::util::get>(outputs[0]); + ASSERT_TRUE(opt_mat.has_value()); + out_mat = *opt_mat; + break; + } + default: GAPI_Assert(false && "Incorrect type of Args"); + } + + EXPECT_EQ(0., cv::norm(ref, out_mat, cv::NORM_INF)); +} + } // anonymous namespace TEST_P(GAPI_Streaming, SmokeTest_ConstInput_GMat) @@ -260,8 +312,7 @@ TEST_P(GAPI_Streaming, SmokeTest_ConstInput_GMat) } // Compilation & testing - auto ccomp = c.compileStreaming(cv::descr_of(in_mat), - cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + auto ccomp = c.compileStreaming(cv::descr_of(in_mat), getCompileArgs()); EXPECT_TRUE(ccomp); EXPECT_FALSE(ccomp.running()); @@ -306,7 +357,7 @@ TEST_P(GAPI_Streaming, SmokeTest_VideoInput_GMat) // Compilation & testing auto ccomp = c.compileStreaming(cv::GMatDesc{CV_8U,3,cv::Size{768,576}}, - cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + getCompileArgs()); EXPECT_TRUE(ccomp); EXPECT_FALSE(ccomp.running()); @@ -356,7 +407,7 @@ TEST_P(GAPI_Streaming, Regression_CompileTimeScalar) cv::GComputation c(cv::GIn(in), cv::GOut(tmp, tmp + 1)); auto ccomp = c.compileStreaming(cv::GMatDesc{CV_8U,3,cv::Size{768,512}}, - cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + getCompileArgs()); cv::Mat in_mat = cv::imread(findDataFile("cv/edgefilter/kodim23.png")); cv::Mat out_mat1, out_mat2; @@ -379,7 +430,7 @@ TEST_P(GAPI_Streaming, SmokeTest_StartRestart) cv::GComputation c(cv::GIn(in), cv::GOut(cv::gapi::copy(in), out)); auto ccomp = c.compileStreaming(cv::GMatDesc{CV_8U,3,cv::Size{768,576}}, - cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + getCompileArgs()); EXPECT_TRUE(ccomp); EXPECT_FALSE(ccomp.running()); @@ -424,8 +475,7 @@ TEST_P(GAPI_Streaming, SmokeTest_VideoConstSource_NoHang) auto refc = cv::GComputation([](){ cv::GMat in; return cv::GComputation(in, cv::gapi::copy(in)); - }).compileStreaming(cv::GMatDesc{CV_8U,3,cv::Size{768,576}}, - cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + }).compileStreaming(cv::GMatDesc{CV_8U,3,cv::Size{768,576}}, getCompileArgs()); auto path = findDataFile("cv/video/768x576.avi"); try { @@ -447,7 +497,7 @@ TEST_P(GAPI_Streaming, SmokeTest_VideoConstSource_NoHang) auto testc = cv::GComputation(cv::GIn(in, in2), cv::GOut(out)) .compileStreaming(cv::GMatDesc{CV_8U,3,cv::Size{256,256}}, cv::GMatDesc{CV_8U,3,cv::Size{768,576}}, - cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + getCompileArgs()); cv::Mat in_const = cv::Mat::eye(cv::Size(256,256), CV_8UC3); testc.setSource(cv::gin(in_const, @@ -468,7 +518,7 @@ TEST_P(GAPI_Streaming, SmokeTest_AutoMeta) cv::GMat out = blr - in; auto testc = cv::GComputation(cv::GIn(in, in2), cv::GOut(out)) - .compileStreaming(cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + .compileStreaming(getCompileArgs()); cv::Mat in_const = cv::Mat::eye(cv::Size(256,256), CV_8UC3); cv::Mat tmp; @@ -510,7 +560,7 @@ TEST_P(GAPI_Streaming, SmokeTest_AutoMeta_2xConstMat) cv::GMat out = blr - in; auto testc = cv::GComputation(cv::GIn(in, in2), cv::GOut(out)) - .compileStreaming(cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + .compileStreaming(getCompileArgs()); cv::Mat in_const = cv::Mat::eye(cv::Size(256,256), CV_8UC3); cv::Mat tmp; @@ -541,7 +591,7 @@ TEST_P(GAPI_Streaming, SmokeTest_AutoMeta_VideoScalar) cv::GMat out_m = in_m * in_s; auto testc = cv::GComputation(cv::GIn(in_m, in_s), cv::GOut(out_m)) - .compileStreaming(cv::compile_args(cv::gapi::use_only{getKernelPackage()})); + .compileStreaming(getCompileArgs()); cv::Mat tmp; // Test with one video source and scalar @@ -572,11 +622,13 @@ TEST_P(GAPI_Streaming, SmokeTest_AutoMeta_VideoScalar) } INSTANTIATE_TEST_CASE_P(TestStreaming, GAPI_Streaming, - Values( KernelPackage::OCV - //, KernelPackage::OCL // FIXME: Fails bit-exactness check, maybe relax it? - , KernelPackage::OCV_FLUID - //, KernelPackage::OCL // FIXME: Fails bit-exactness check, maybe relax it? - )); + Combine(Values( KernelPackage::OCV + //, KernelPackage::OCL // FIXME: Fails bit-exactness check, maybe relax it? + , KernelPackage::OCV_FLUID + //, KernelPackage::OCL // FIXME: Fails bit-exactness check, maybe relax it? + ), + Values(cv::optional{}, 1u, 4u)) + ); namespace TypesTest { @@ -653,8 +705,15 @@ TEST_P(GAPI_Streaming, SmokeTest_AutoMeta_VideoArray) cv::GMat out_m = TypesTest::AddV::on(in_m, in_v) - in_m; // Run pipeline + auto args = cv::compile_args(cv::gapi::kernels()); + auto capacity = getQueueCapacity(); + if (capacity) + { + args += cv::compile_args( + cv::gapi::streaming::queue_capacity{capacity.value()}); + } auto testc = cv::GComputation(cv::GIn(in_m, in_v), cv::GOut(out_m)) - .compileStreaming(cv::compile_args(cv::gapi::kernels())); + .compileStreaming(std::move(args)); cv::Mat tmp; // Test with one video source and vector @@ -1306,13 +1365,45 @@ TEST(Streaming, Python_Pull_Overload) bool has_output; cv::GRunArgs outputs; - std::tie(has_output, outputs) = ccomp.pull(); + using RunArgs = cv::util::variant; + RunArgs args; - EXPECT_TRUE(has_output); - EXPECT_EQ(1u, outputs.size()); + std::tie(has_output, args) = ccomp.pull(); - auto out_mat = cv::util::get(outputs[0]); - EXPECT_EQ(0., cv::norm(in_mat, out_mat, cv::NORM_INF)); + checkPullOverload(in_mat, has_output, args); + + ccomp.stop(); + EXPECT_FALSE(ccomp.running()); +} + +TEST(GAPI_Streaming_Desync, Python_Pull_Overload) +{ + cv::GMat in; + cv::GMat out = cv::gapi::streaming::desync(in); + cv::GComputation c(in, out); + + cv::Size sz(3,3); + cv::Mat in_mat(sz, CV_8UC3); + cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar(255)); + + auto ccomp = c.compileStreaming(); + + EXPECT_TRUE(ccomp); + EXPECT_FALSE(ccomp.running()); + + ccomp.setSource(cv::gin(in_mat)); + + ccomp.start(); + EXPECT_TRUE(ccomp.running()); + + bool has_output; + cv::GRunArgs outputs; + using RunArgs = cv::util::variant; + RunArgs args; + + std::tie(has_output, args) = ccomp.pull(); + + checkPullOverload(in_mat, has_output, args); ccomp.stop(); EXPECT_FALSE(ccomp.running()); @@ -2102,9 +2193,17 @@ TEST(GAPI_Streaming, TestPythonAPI) bool is_over = false; cv::GRunArgs out_args; + using RunArgs = cv::util::variant; + RunArgs args; // NB: Used by python bridge - std::tie(is_over, out_args) = cc.pull(); + std::tie(is_over, args) = cc.pull(); + + switch (args.index()) { + case RunArgs::index_of(): + out_args = util::get(args); break; + default: GAPI_Assert(false && "Incorrect type of return value"); + } ASSERT_EQ(1u, out_args.size()); ASSERT_TRUE(cv::util::holds_alternative(out_args[0])); diff --git a/modules/gapi/test/util/variant_tests.cpp b/modules/gapi/test/util/variant_tests.cpp index 65d5e579f81b..7725f9a70211 100644 --- a/modules/gapi/test/util/variant_tests.cpp +++ b/modules/gapi/test/util/variant_tests.cpp @@ -354,6 +354,20 @@ TEST(Variant, Get) EXPECT_THROW(util::get(cv2), util::bad_variant_access); } +TEST(Variant, GetIndexed) +{ + const TestVar cv(42); + + // Test const& get() + EXPECT_EQ(42, util::get<0>(cv)); + EXPECT_THROW(util::get<1>(cv), util::bad_variant_access); + + // Test &get + TestVar cv2(std::string("42")); + EXPECT_EQ("42", util::get<1>(cv2)); + EXPECT_THROW(util::get<0>(cv2), util::bad_variant_access); +} + TEST(Variant, GetWrite) { util::variant v(42); @@ -486,4 +500,240 @@ TEST(Variant, EXT_IndexOf) static_assert(6u == V::index_of(), "Index is incorrect"); } +namespace test_validation +{ +struct MyType +{ + friend std::ostream& operator<<(std::ostream& out, const MyType& src) + { + return out << "MyType"; (void) src; + } +}; +class MyClass +{ + friend std::ostream& operator<<(std::ostream& out, const MyClass& src) + { + return out << "MyClass"; (void) src; + } +}; + +struct MyBoolParamIndexedVisitor : cv::util::static_indexed_visitor +{ + MyBoolParamIndexedVisitor(std::ostream &output) : out(output) {} + + template + bool visit(std::size_t index, Type val, int check) + { + bool result = false; + out << index << ":" << val <<","; + if(std::is_same::value) + { + result = !memcmp(&val, &check, sizeof(int)); + } + return result; + } + + std::ostream &out; +}; + +struct MyBoolNoParamNonIndexedVisitor : cv::util::static_indexed_visitor +{ + MyBoolNoParamNonIndexedVisitor(std::ostream &output) : out(output) {} + + template + bool visit(std::size_t index, Type val) + { + out << index << ":" << val <<","; + return true; + } + std::ostream &out; +}; + + +struct MyVoidNoParamNonIndexedVisitor : cv::util::static_visitor +{ + MyVoidNoParamNonIndexedVisitor(std::ostream &output) : out(output) {} + + template + void visit(Type val) + { + out << val << ","; + } + + std::ostream &out; +}; + + +struct MyVoidNoParamIndexedVisitor : cv::util::static_indexed_visitor +{ + MyVoidNoParamIndexedVisitor(std::ostream &output) : out(output) {} + + template + void visit(std::size_t Index, Type val) + { + out << Index << ":" << val <<","; + } + + std::ostream &out; +}; +} + +TEST(Variant, DynamicVisitor) +{ + using V = cv::util::variant; + V var{42}; + { + std::stringstream ss; + test_validation::MyBoolParamIndexedVisitor visitor(ss); + + EXPECT_TRUE(cv::util::visit(visitor, var, int{42})); + EXPECT_EQ(ss.str(), std::string("0:42,")); + } + + std::stringstream ss; + test_validation::MyBoolNoParamNonIndexedVisitor visitor(ss); + + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("0:42,")); + + var = double{1.0}; + EXPECT_TRUE(cv::util::visit(visitor, var)); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,")); + + var = char{'a'}; + EXPECT_TRUE(cv::util::visit(visitor, var)); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,")); + + var = float{6.0}; + EXPECT_TRUE(cv::util::visit(visitor, var)); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,3:6,")); + + var = test_validation::MyType{}; + EXPECT_TRUE(cv::util::visit(visitor, var)); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,3:6,4:MyType,")); + + var = test_validation::MyClass{}; + EXPECT_TRUE(cv::util::visit(visitor, var)); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,3:6,4:MyType,5:MyClass,")); +} + +TEST(Variant, StaticVisitor) +{ + using V = cv::util::variant; + V var{42}; + std::stringstream ss; + test_validation::MyVoidNoParamNonIndexedVisitor visitor(ss); + + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("42,")); + + var = double{1.0}; + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("42,1,")); + + var = char{'a'}; + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("42,1,a,")); + + var = float{6.0}; + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("42,1,a,6,")); + + var = test_validation::MyType{}; + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("42,1,a,6,MyType,")); + + var = test_validation::MyClass{}; + cv::util::visit(visitor, var); + EXPECT_EQ(ss.str(), std::string("42,1,a,6,MyType,MyClass,")); +} + +TEST(Variant, StaticIndexedVisitor) +{ + using V = cv::util::variant; + V var{42}; + + std::stringstream ss; + cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor {ss}, var); + EXPECT_EQ(ss.str(), std::string("0:42,")); + + var = double{1.0}; + cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,")); + + var = char{'a'}; + cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,")); + + var = float{6.0}; + cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,3:6,")); + + var = test_validation::MyType{}; + cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,3:6,4:MyType,")); + + var = test_validation::MyClass{}; + cv::util::visit(test_validation::MyVoidNoParamIndexedVisitor (ss), var); + EXPECT_EQ(ss.str(), std::string("0:42,1:1,2:a,3:6,4:MyType,5:MyClass,")); +} + + +TEST(Variant, LambdaVisitor) +{ + using V = cv::util::variant; + V var{42}; + { + cv::util::visit(cv::util::overload_lambdas( + [](int value) { + EXPECT_EQ(value, 42); + }, + [](double) { + ADD_FAILURE() << "can't be called for `double`"; + }, + [](char) { + ADD_FAILURE() << "can't be called for `char`"; + }, + [](float) { + ADD_FAILURE() << "can't be called for `float`"; + }, + [](test_validation::MyType) { + ADD_FAILURE() << "can't be called for `MyType`"; + }, + [](test_validation::MyClass) { + ADD_FAILURE() << "can't be called for `MyClass`"; + }, + [](std::string) { + ADD_FAILURE() << "can't be called for `std::string`, invalid type"; + } + ), var); + } + + var = 'c'; + { + cv::util::visit(cv::util::overload_lambdas( + [](int) { + ADD_FAILURE() << "can't be called for `int`"; + }, + [](double) { + ADD_FAILURE() << "can't be called for `double`"; + }, + [](char value) { + EXPECT_EQ(value, 'c'); + }, + [](float) { + ADD_FAILURE() << "can't be called for `float`"; + }, + [](test_validation::MyType) { + ADD_FAILURE() << "can't be called for `MyType`"; + }, + [](test_validation::MyClass) { + ADD_FAILURE() << "can't be called for `MyClass`"; + }, + [](std::string) { + ADD_FAILURE() << "can't be called for `std::string`, invalid type"; + } + ), var); + } +} } // namespace opencv_test diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index 7a546616a423..bc31b84c74e1 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -1,10 +1,25 @@ set(the_description "High-level GUI") + if(ANDROID) ocv_add_module(highgui opencv_imgproc opencv_imgcodecs OPTIONAL opencv_videoio WRAP python) else() ocv_add_module(highgui opencv_imgproc opencv_imgcodecs OPTIONAL opencv_videoio WRAP python java) endif() +include(${CMAKE_CURRENT_LIST_DIR}/cmake/plugin.cmake) + +set(tgts "PRIVATE") + +set(highgui_hdrs + ${CMAKE_CURRENT_LIST_DIR}/src/precomp.hpp + ) + +set(highgui_srcs + ${CMAKE_CURRENT_LIST_DIR}/src/backend.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/window.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/roiSelector.cpp + ) + # ---------------------------------------------------------------------------- # CMake file for highgui. See root CMakeLists.txt # Some parts taken from version of Hartmut Seichter, HIT Lab NZ. @@ -24,15 +39,6 @@ if(HAVE_WEBP) add_definitions(-DHAVE_WEBP) endif() -set(highgui_hdrs - ${CMAKE_CURRENT_LIST_DIR}/src/precomp.hpp - ) - -set(highgui_srcs - ${CMAKE_CURRENT_LIST_DIR}/src/window.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/roiSelector.cpp - ) - file(GLOB highgui_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/*.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp" @@ -41,7 +47,12 @@ file(GLOB highgui_ext_hdrs # Removing WinRT API headers by default list(REMOVE_ITEM highgui_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/highgui_winrt.hpp") +set(OPENCV_HIGHGUI_BUILTIN_BACKEND "") + if(HAVE_QT5) + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "QT5") + add_definitions(-DHAVE_QT) + # "Automoc" doesn't work properly with opencv_world build, use QT5_WRAP_CPP() directly #set(CMAKE_AUTOMOC ON) @@ -62,13 +73,16 @@ if(HAVE_QT5) endforeach() if(HAVE_QT_OPENGL) + add_definitions(-DHAVE_QT_OPENGL) add_definitions(${Qt5OpenGL_DEFINITIONS}) include_directories(${Qt5OpenGL_INCLUDE_DIRS}) list(APPEND HIGHGUI_LIBRARIES ${Qt5OpenGL_LIBRARIES}) endif() - elseif(HAVE_QT) - if (HAVE_QT_OPENGL) + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "QT4") + add_definitions(-DHAVE_QT) + if(HAVE_QT_OPENGL) + add_definitions(-DHAVE_QT_OPENGL) set(QT_USE_QTOPENGL TRUE) endif() include(${QT_USE_FILE}) @@ -83,6 +97,7 @@ elseif(HAVE_QT) set_source_files_properties(${_RCC_OUTFILES} PROPERTIES COMPILE_FLAGS -Wno-missing-declarations) endif() elseif(WINRT) + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WINRT") if(NOT WINRT_8_0) # Dependencies used by the implementation referenced # below are not available on WinRT 8.0. @@ -116,18 +131,95 @@ elseif(WINRT) message(STATUS " ${name}: Removing 'comctl32.lib, gdi32.lib, ole32.lib, setupapi.lib'") message(STATUS " ${name}: Leaving '${HIGHGUI_LIBRARIES}'") endif() -elseif(HAVE_WIN32UI) - list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_w32.cpp) - if(OpenCV_ARCH STREQUAL "ARM64") - list(APPEND HIGHGUI_LIBRARIES "comdlg32" "advapi32") - endif() -elseif(HAVE_GTK OR HAVE_GTK3) - list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_gtk.cpp) elseif(HAVE_COCOA) + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "COCOA") + add_definitions(-DHAVE_COCOA) list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_cocoa.mm) list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa") endif() +if(TARGET ocv.3rdparty.win32ui) + if("win32ui" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all") + ocv_create_builtin_highgui_plugin(opencv_highgui_win32 ocv.3rdparty.win32ui "window_w32.cpp") + elseif(NOT OPENCV_HIGHGUI_BUILTIN_BACKEND) + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WIN32UI") + list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_w32.cpp) + list(APPEND tgts ocv.3rdparty.win32ui) + endif() +endif() + +if(TARGET ocv.3rdparty.gtk3 OR TARGET ocv.3rdparty.gtk2) + if(TARGET ocv.3rdparty.gtk3 AND NOT WITH_GTK_2_X) + set(__gtk_dependency "ocv.3rdparty.gtk3") + else() + set(__gtk_dependency "ocv.3rdparty.gtk2") + endif() + if( + NOT HIGHGUI_PLUGIN_LIST STREQUAL "all" + AND NOT "gtk" IN_LIST HIGHGUI_PLUGIN_LIST + AND NOT "gtk2" IN_LIST HIGHGUI_PLUGIN_LIST + AND NOT "gtk3" IN_LIST HIGHGUI_PLUGIN_LIST + AND NOT OPENCV_HIGHGUI_BUILTIN_BACKEND + ) + if(__gtk_dependency STREQUAL "ocv.3rdparty.gtk3") + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK3") + elseif(__gtk_dependency STREQUAL "ocv.3rdparty.gtk2") + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK2") + else() + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK") + endif() + list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_gtk.cpp) + list(APPEND tgts ${__gtk_dependency}) + if(TARGET ocv.3rdparty.gthread) + list(APPEND tgts ocv.3rdparty.gthread) + endif() + if(TARGET ocv.3rdparty.gtkglext + AND __gtk_dependency STREQUAL "ocv.3rdparty.gtk2" + AND NOT OPENCV_GTK_DISABLE_GTKGLEXT + ) + list(APPEND tgts ocv.3rdparty.gtkglext) + if(TARGET ocv.3rdparty.gtk_opengl + AND __gtk_dependency STREQUAL "ocv.3rdparty.gtk2" + AND NOT OPENCV_GTK_DISABLE_OPENGL + ) + list(APPEND tgts ocv.3rdparty.gtk_opengl) + endif() + endif() + elseif("gtk" IN_LIST HIGHGUI_PLUGIN_LIST) + ocv_create_builtin_highgui_plugin(opencv_highgui_gtk ${__gtk_dependency} "window_gtk.cpp") + if(TARGET ocv.3rdparty.gthread) + ocv_target_link_libraries(opencv_highgui_gtk ocv.3rdparty.gthread) + endif() + if(TARGET ocv.3rdparty.gtkglext) + ocv_target_link_libraries(opencv_highgui_gtk ocv.3rdparty.gtkglext) + endif() + else() + if(TARGET ocv.3rdparty.gtk3 AND ("gtk3" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all")) + ocv_create_builtin_highgui_plugin(opencv_highgui_gtk3 ocv.3rdparty.gtk3 "window_gtk.cpp") + if(TARGET ocv.3rdparty.gthread) + ocv_target_link_libraries(opencv_highgui_gtk3 ocv.3rdparty.gthread) + endif() + if(TARGET ocv.3rdparty.gtkglext) + ocv_target_link_libraries(opencv_highgui_gtk3 ocv.3rdparty.gtkglext) + endif() + endif() + if(TARGET ocv.3rdparty.gtk2 AND ("gtk2" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all")) + ocv_create_builtin_highgui_plugin(opencv_highgui_gtk2 ocv.3rdparty.gtk2 "window_gtk.cpp") + if(TARGET ocv.3rdparty.gthread) + ocv_target_link_libraries(opencv_highgui_gtk2 ocv.3rdparty.gthread) + endif() + if(TARGET ocv.3rdparty.gtkglext) + ocv_target_link_libraries(opencv_highgui_gtk2 ocv.3rdparty.gtkglext) + endif() + endif() + endif() +endif() + +if(NOT OPENCV_HIGHGUI_BUILTIN_BACKEND) + set(OPENCV_HIGHGUI_BUILTIN_BACKEND "NONE") +endif() +message(STATUS "highgui: using builtin backend: ${OPENCV_HIGHGUI_BUILTIN_BACKEND}") # FIXIT: propagate to root CMake + if(TRUE) # these variables are set by 'ocv_append_build_options(HIGHGUI ...)' foreach(P ${HIGHGUI_INCLUDE_DIRS}) @@ -139,6 +231,21 @@ if(TRUE) endforeach() endif() +if(tgts STREQUAL "PRIVATE") + set(tgts "") +endif() + +# install used dependencies only +if(NOT BUILD_SHARED_LIBS + AND NOT (CMAKE_VERSION VERSION_LESS "3.13.0") # upgrade CMake: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/2152 +) + foreach(tgt in ${tgts}) + if(tgt MATCHES "^ocv\.3rdparty\.") + install(TARGETS ${tgt} EXPORT OpenCVModules) + endif() + endforeach() +endif() + source_group("Src" FILES ${highgui_srcs} ${highgui_hdrs}) source_group("Include" FILES ${highgui_ext_hdrs}) ocv_set_module_sources(HEADERS ${highgui_ext_hdrs} SOURCES ${highgui_srcs} ${highgui_hdrs}) @@ -162,5 +269,26 @@ if(NOT BUILD_opencv_world) ocv_highgui_configure_target() endif() -ocv_add_accuracy_tests() -ocv_add_perf_tests() +ocv_add_accuracy_tests(${tgts}) +#ocv_add_perf_tests(${tgts}) + +if(HIGHGUI_ENABLE_PLUGINS) + ocv_target_compile_definitions(${the_module} PRIVATE ENABLE_PLUGINS) + if(TARGET opencv_test_highgui) + ocv_target_compile_definitions(opencv_test_highgui PRIVATE ENABLE_PLUGINS) + endif() +endif() + +ocv_target_link_libraries(${the_module} LINK_PRIVATE ${tgts}) + +# generate module configuration +set(CONFIG_STR "// Auto-generated file +#define OPENCV_HIGHGUI_BUILTIN_BACKEND_STR \"${OPENCV_HIGHGUI_BUILTIN_BACKEND}\" +") +if(OPENCV_HIGHGUI_BUILTIN_BACKEND STREQUAL "NONE") +set(CONFIG_STR "${CONFIG_STR} +#define OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND 1 +") +endif() + +ocv_update_file("${CMAKE_CURRENT_BINARY_DIR}/opencv_highgui_config.hpp" "${CONFIG_STR}") diff --git a/modules/highgui/cmake/detect_gtk.cmake b/modules/highgui/cmake/detect_gtk.cmake new file mode 100644 index 000000000000..cdc054fad0c5 --- /dev/null +++ b/modules/highgui/cmake/detect_gtk.cmake @@ -0,0 +1,56 @@ +# --- GTK --- +ocv_clear_vars(HAVE_GTK HAVE_GTK2 HAVE_GTK3 HAVE_GTHREAD HAVE_GTKGLEXT) +if(WITH_GTK) + if(NOT WITH_GTK_2_X) + ocv_check_modules(GTK3 gtk+-3.0) + if(HAVE_GTK3) + ocv_add_external_target(gtk3 "${GTK3_INCLUDE_DIRS}" "${GTK3_LIBRARIES}" "HAVE_GTK3;HAVE_GTK") + set(HAVE_GTK TRUE) + set(HAVE_GTK3 ${HAVE_GTK3} PARENT_SCOPE) + set(GTK3_VERSION "${GTK3_VERSION}" PARENT_SCOPE) # informational + endif() + endif() + if((PROJECT_NAME STREQUAL "OpenCV" AND HIGHGUI_ENABLE_PLUGINS) OR NOT HAVE_GTK3) + ocv_check_modules(GTK2 gtk+-2.0) + if(HAVE_GTK2) + set(MIN_VER_GTK "2.18.0") + if(GTK2_VERSION VERSION_LESS MIN_VER_GTK) + message(FATAL_ERROR "GTK support requires a minimum version of ${MIN_VER_GTK} (${GTK2_VERSION} found)") + else() + ocv_add_external_target(gtk2 "${GTK2_INCLUDE_DIRS}" "${GTK2_LIBRARIES}" "HAVE_GTK2;HAVE_GTK") + set(HAVE_GTK TRUE) + set(HAVE_GTK2 ${HAVE_GTK2} PARENT_SCOPE) + set(GTK2_VERSION "${GTK2_VERSION}" PARENT_SCOPE) # informational + endif() + endif() + endif() + ocv_check_modules(GTHREAD gthread-2.0) + if(HAVE_GTK AND NOT HAVE_GTHREAD) + message(FATAL_ERROR "gthread not found. This library is required when building with GTK support") + else() + ocv_add_external_target(gthread "${GTHREAD_INCLUDE_DIRS}" "${GTHREAD_LIBRARIES}" "HAVE_GTHREAD") + set(HAVE_GTHREAD "${HAVE_GTHREAD}" PARENT_SCOPE) # informational + set(GTHREAD_VERSION "${GTHREAD_VERSION}" PARENT_SCOPE) # informational + endif() + if((WITH_OPENGL OR HAVE_OPENGL) AND HAVE_GTK2) + ocv_check_modules(GTKGLEXT gtkglext-1.0) + if(HAVE_GTKGLEXT) + ocv_add_external_target(gtkglext "${GTKGLEXT_INCLUDE_DIRS}" "${GTKGLEXT_LIBRARIES}" "HAVE_GTKGLEXT") + set(HAVE_GTKGLEXT "${HAVE_GTKGLEXT}" PARENT_SCOPE) # informational + set(GTKGLEXT_VERSION "${GTKGLEXT_VERSION}" PARENT_SCOPE) # informational + endif() + endif() +elseif(HAVE_GTK) + ocv_add_external_target(gtk "${GTK_INCLUDE_DIRS}" "${GTK_LIBRARIES}" "${GTK_DEFINES};HAVE_GTK") +endif() + +if(WITH_OPENGL AND HAVE_GTKGLEXT) + find_package(OpenGL QUIET) + if(OPENGL_FOUND) + set(HAVE_OPENGL TRUE) + #set(HAVE_OPENGL ${HAVE_OPENGL} PARENT_SCOPE) + ocv_add_external_target(gtk_opengl "${OPENGL_INCLUDE_DIRS}" "${OPENGL_LIBRARIES}" "HAVE_OPENGL") + endif() +endif() + +set(HAVE_GTK ${HAVE_GTK} PARENT_SCOPE) diff --git a/modules/highgui/cmake/detect_win32ui.cmake b/modules/highgui/cmake/detect_win32ui.cmake new file mode 100644 index 000000000000..1d2fdc5d4654 --- /dev/null +++ b/modules/highgui/cmake/detect_win32ui.cmake @@ -0,0 +1,17 @@ +#--- Win32 UI --- +ocv_clear_vars(HAVE_WIN32UI) +if(WITH_WIN32UI) + try_compile(HAVE_WIN32UI + "${CMAKE_CURRENT_BINARY_DIR}" + "${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp" + CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32") + if(HAVE_WIN32UI) + set(__libs "user32" "gdi32") + if(OpenCV_ARCH STREQUAL "ARM64") + list(APPEND __libs "comdlg32" "advapi32") + endif() + ocv_add_external_target(win32ui "" "${__libs}" "HAVE_WIN32UI") + endif() +endif() + +set(HAVE_WIN32UI "${HAVE_WIN32UI}" PARENT_SCOPE) # informational diff --git a/modules/highgui/cmake/init.cmake b/modules/highgui/cmake/init.cmake new file mode 100644 index 000000000000..1626d254daf9 --- /dev/null +++ b/modules/highgui/cmake/init.cmake @@ -0,0 +1,51 @@ +if(PROJECT_NAME STREQUAL "OpenCV") + set(ENABLE_PLUGINS_DEFAULT ON) + if(EMSCRIPTEN OR IOS OR WINRT) + set(ENABLE_PLUGINS_DEFAULT OFF) + endif() + set(HIGHGUI_PLUGIN_LIST "" CACHE STRING "List of GUI backends to be compiled as plugins (gtk, gtk2/gtk3, qt, win32 or special value 'all')") + set(HIGHGUI_ENABLE_PLUGINS "${ENABLE_PLUGINS_DEFAULT}" CACHE BOOL "Allow building and using of GUI plugins") + mark_as_advanced(HIGHGUI_PLUGIN_LIST HIGHGUI_ENABLE_PLUGINS) + + string(REPLACE "," ";" HIGHGUI_PLUGIN_LIST "${HIGHGUI_PLUGIN_LIST}") # support comma-separated list (,) too + if(NOT HIGHGUI_ENABLE_PLUGINS) + if(HIGHGUI_PLUGIN_LIST) + message(WARNING "HighGUI: plugins are disabled through HIGHGUI_ENABLE_PLUGINS, so HIGHGUI_PLUGIN_LIST='${HIGHGUI_PLUGIN_LIST}' is ignored") + set(HIGHGUI_PLUGIN_LIST "") + endif() + else() + # Make virtual plugins target + if(NOT TARGET opencv_highgui_plugins) + add_custom_target(opencv_highgui_plugins ALL) + endif() + endif() +endif() + +# +# Detect available dependencies +# + +include(FindPkgConfig) + +# FIXIT: stop using PARENT_SCOPE in dependencies +if(PROJECT_NAME STREQUAL "OpenCV") + macro(add_backend backend_id cond_var) + if(${cond_var}) + include("${CMAKE_CURRENT_LIST_DIR}/detect_${backend_id}.cmake") + endif() + endmacro() +else() + function(add_backend backend_id cond_var) + if(${cond_var}) + include("${CMAKE_CURRENT_LIST_DIR}/detect_${backend_id}.cmake") + endif() + endfunction() +endif() + +add_backend("gtk" WITH_GTK) +add_backend("win32ui" WITH_WIN32UI) +# TODO cocoa +# TODO qt +# TODO opengl + +# FIXIT: move content of cmake/OpenCVFindLibsGUI.cmake here (need to resolve CMake scope issues) diff --git a/modules/highgui/cmake/plugin.cmake b/modules/highgui/cmake/plugin.cmake new file mode 100644 index 000000000000..6e0ddd2dc502 --- /dev/null +++ b/modules/highgui/cmake/plugin.cmake @@ -0,0 +1,61 @@ +function(ocv_create_builtin_highgui_plugin name target) + + ocv_debug_message("ocv_create_builtin_highgui_plugin(${ARGV})") + + if(NOT TARGET ${target}) + message(FATAL_ERROR "${target} does not exist!") + endif() + if(NOT OpenCV_SOURCE_DIR) + message(FATAL_ERROR "OpenCV_SOURCE_DIR must be set to build the plugin!") + endif() + + message(STATUS "HighGUI: add builtin plugin '${name}'") + + foreach(src ${ARGN}) + list(APPEND sources "${CMAKE_CURRENT_LIST_DIR}/src/${src}") + endforeach() + + add_library(${name} MODULE ${sources}) + target_include_directories(${name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + target_compile_definitions(${name} PRIVATE BUILD_PLUGIN) + target_link_libraries(${name} PRIVATE ${target}) + + foreach(mod opencv_highgui + opencv_core + opencv_imgproc + opencv_imgcodecs + opencv_videoio # TODO remove this dependency + ) + ocv_target_link_libraries(${name} LINK_PRIVATE ${mod}) + ocv_target_include_directories(${name} "${OPENCV_MODULE_${mod}_LOCATION}/include") + endforeach() + + if(WIN32) + set(OPENCV_PLUGIN_VERSION "${OPENCV_DLLVERSION}" CACHE STRING "") + if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) + set(OPENCV_PLUGIN_ARCH "_64" CACHE STRING "") + else() + set(OPENCV_PLUGIN_ARCH "" CACHE STRING "") + endif() + else() + set(OPENCV_PLUGIN_VERSION "" CACHE STRING "") + set(OPENCV_PLUGIN_ARCH "" CACHE STRING "") + endif() + + set_target_properties(${name} PROPERTIES + CXX_STANDARD 11 + CXX_VISIBILITY_PRESET hidden + DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" + OUTPUT_NAME "${name}${OPENCV_PLUGIN_VERSION}${OPENCV_PLUGIN_ARCH}" + ) + + if(WIN32) + set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) + install(TARGETS ${name} OPTIONAL LIBRARY DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT plugins) + else() + install(TARGETS ${name} OPTIONAL LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT plugins) + endif() + + add_dependencies(opencv_highgui_plugins ${name}) + +endfunction() diff --git a/modules/highgui/misc/plugins/build_plugins.sh b/modules/highgui/misc/plugins/build_plugins.sh new file mode 100755 index 000000000000..0018eef3ba14 --- /dev/null +++ b/modules/highgui/misc/plugins/build_plugins.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e + +if [ -z $1 ] ; then + echo "$0 " + exit 1 +fi + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +OCV="$( cd "${DIR}/../../../.." >/dev/null 2>&1 && pwd )" +mkdir -p "${1}" # Docker creates non-existed mounts with 'root' owner, lets ensure that dir exists under the current user to avoid "Permission denied" problem +DST="$( cd "$1" >/dev/null 2>&1 && pwd )" +CFG=${2:-Release} + +do_build() +{ +TAG=$1 +D=$2 +F=$3 +shift 3 +docker build \ + --build-arg http_proxy \ + --build-arg https_proxy \ + $@ \ + -t $TAG \ + -f "${D}/${F}" \ + "${D}" +} + +do_run() +{ +TAG=$1 +shift 1 +docker run \ + -it \ + --rm \ + -v "${OCV}":/opencv:ro \ + -v "${DST}":/dst \ + -e CFG=$CFG \ + --user $(id -u):$(id -g) \ + $TAG \ + "$@" +} + +build_gtk2_ubuntu() +{ +VER=$1 +shift 1 +TAG=opencv_highgui_ubuntu_gtk2_builder:${VER} +do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk2 --build-arg VER=${VER} +do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk2_ubuntu${VER} ${CFG} "$@" + +} + +build_gtk3_ubuntu() +{ +VER=$1 +shift 1 +TAG=opencv_highgui_ubuntu_gtk3_builder:${VER} +do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk3 --build-arg VER=${VER} +do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk3_ubuntu${VER} ${CFG} "$@" +} + +echo "OpenCV: ${OCV}" +echo "Destination: ${DST}" + +build_gtk2_ubuntu 16.04 +build_gtk2_ubuntu 16.04 -DOPENCV_PLUGIN_NAME=opencv_highgui_gtk2-opengl_ubuntu16.04 -DWITH_OPENGL=ON -DWITH_GTK_2_X=ON +build_gtk2_ubuntu 18.04 +build_gtk3_ubuntu 18.04 +build_gtk3_ubuntu 20.04 diff --git a/modules/highgui/misc/plugins/plugin_gtk/CMakeLists.txt b/modules/highgui/misc/plugins/plugin_gtk/CMakeLists.txt new file mode 100644 index 000000000000..6a2da0c9c329 --- /dev/null +++ b/modules/highgui/misc/plugins/plugin_gtk/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 3.5) +project(opencv_highgui_gtk) + +get_filename_component(OpenCV_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../.." ABSOLUTE) +include("${OpenCV_SOURCE_DIR}/cmake/OpenCVPluginStandalone.cmake") + +# scan dependencies +set(WITH_GTK ON) +include("${OpenCV_SOURCE_DIR}/modules/highgui/cmake/init.cmake") + +if(NOT HAVE_GTK) + message(FATAL_ERROR "GTK: NO") +endif() + +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations) + +set(OPENCV_PLUGIN_DEPS core imgproc imgcodecs) +if(TARGET ocv.3rdparty.gtk3) + set(__deps ocv.3rdparty.gtk3) +elseif(TARGET ocv.3rdparty.gtk2) + set(__deps ocv.3rdparty.gtk2) +elseif(TARGET ocv.3rdparty.gtk) + set(__deps ocv.3rdparty.gtk) +else() + message(FATAL_ERROR "Missing dependency target for GTK libraries") +endif() +ocv_create_plugin(highgui "opencv_highgui_gtk" "${__deps}" "GTK" "src/window_gtk.cpp") +if(WITH_OPENGL) + if(HAVE_GTK2 + AND TARGET ocv.3rdparty.gtkglext + AND TARGET ocv.3rdparty.gtk_opengl + AND NOT OPENCV_GTK_DISABLE_GTKGLEXT + AND NOT OPENCV_GTK_DISABLE_OPENGL + ) + message(STATUS "OpenGL: YES") + target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE + ocv.3rdparty.gtkglext ocv.3rdparty.gtk_opengl + ) + else() + message(WARNING "OpenGL dependencies are not available!") + endif() +endif() + +if(HAVE_GTK3) + message(STATUS "GTK3+: ver ${GTK3_VERSION}") +elseif(HAVE_GTK3) + message(STATUS "GTK2+: ver ${GTK2_VERSION}") +elseif(DEFINED GTK_VERSION) + message(STATUS "GTK+: ver ${GTK_VERSION}") +else() + message(STATUS "GTK+: YES") +endif() + +if(HAVE_GTHREAD) + message(STATUS "GThread : YES (ver ${GTHREAD_VERSION})") +else() + message(STATUS "GThread : NO") +endif() diff --git a/modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk2 b/modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk2 new file mode 100644 index 000000000000..fefa0ba339b1 --- /dev/null +++ b/modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk2 @@ -0,0 +1,28 @@ +ARG VER +FROM ubuntu:$VER + +RUN \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + pkg-config \ + cmake \ + g++ \ + ninja-build \ + && \ + rm -rf /var/lib/apt/lists/* + +RUN \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libgtk2.0-dev \ + && \ + rm -rf /var/lib/apt/lists/* + +RUN \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libgtkglext1-dev \ + && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /tmp diff --git a/modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk3 b/modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk3 new file mode 100644 index 000000000000..2c6625ae14de --- /dev/null +++ b/modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk3 @@ -0,0 +1,21 @@ +ARG VER +FROM ubuntu:$VER + +RUN \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + pkg-config \ + cmake \ + g++ \ + ninja-build \ + && \ + rm -rf /var/lib/apt/lists/* + +RUN \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libgtk-3-dev \ + && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /tmp diff --git a/modules/highgui/misc/plugins/plugin_gtk/build.sh b/modules/highgui/misc/plugins/plugin_gtk/build.sh new file mode 100755 index 000000000000..4383016910e8 --- /dev/null +++ b/modules/highgui/misc/plugins/plugin_gtk/build.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +OPENCV_PLUGIN_DESTINATION=$1 +OPENCV_PLUGIN_NAME=opencv_highgui_$2 +CMAKE_BUILD_TYPE=${3:-Release} + +shift 3 || true + +set -x +cmake -GNinja \ + -DOPENCV_PLUGIN_NAME=${OPENCV_PLUGIN_NAME} \ + -DOPENCV_PLUGIN_DESTINATION=${OPENCV_PLUGIN_DESTINATION} \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + "$@" \ + $DIR + +ninja -v diff --git a/modules/highgui/src/backend.cpp b/modules/highgui/src/backend.cpp new file mode 100644 index 000000000000..9ea475cecc59 --- /dev/null +++ b/modules/highgui/src/backend.cpp @@ -0,0 +1,181 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +#include "precomp.hpp" +#include "backend.hpp" + +#include +#include +#ifdef NDEBUG +#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG + 1 +#else +#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1 +#endif +#include + + +#include "registry.hpp" +#include "registry.impl.hpp" + +#include "plugin_api.hpp" +#include "plugin_wrapper.impl.hpp" + + +namespace cv { namespace highgui_backend { + +UIBackend::~UIBackend() +{ + // nothing +} + +UIWindowBase::~UIWindowBase() +{ + // nothing +} + +UIWindow::~UIWindow() +{ + // nothing +} + +UITrackbar::~UITrackbar() +{ + // nothing +} + +static +std::string& getUIBackendName() +{ + static std::string g_backendName = toUpperCase(cv::utils::getConfigurationParameterString("OPENCV_UI_BACKEND", "")); + return g_backendName; +} + +static bool g_initializedUIBackend = false; + +static +std::shared_ptr createUIBackend() +{ + const std::string& name = getUIBackendName(); + bool isKnown = false; + const auto& backends = getBackendsInfo(); + if (!name.empty()) + { + CV_LOG_INFO(NULL, "UI: requested backend name: " << name); + } + for (size_t i = 0; i < backends.size(); i++) + { + const auto& info = backends[i]; + if (!name.empty()) + { + if (name != info.name) + { + continue; + } + isKnown = true; + } + try + { + CV_LOG_DEBUG(NULL, "UI: trying backend: " << info.name << " (priority=" << info.priority << ")"); + if (!info.backendFactory) + { + CV_LOG_DEBUG(NULL, "UI: factory is not available (plugins require filesystem support): " << info.name); + continue; + } + std::shared_ptr backend = info.backendFactory->create(); + if (!backend) + { + CV_LOG_VERBOSE(NULL, 0, "UI: not available: " << info.name); + continue; + } + CV_LOG_INFO(NULL, "UI: using backend: " << info.name << " (priority=" << info.priority << ")"); + g_initializedUIBackend = true; + getUIBackendName() = info.name; + return backend; + } + catch (const std::exception& e) + { + CV_LOG_WARNING(NULL, "UI: can't initialize " << info.name << " backend: " << e.what()); + } + catch (...) + { + CV_LOG_WARNING(NULL, "UI: can't initialize " << info.name << " backend: Unknown C++ exception"); + } + } + if (name.empty()) + { + CV_LOG_DEBUG(NULL, "UI: fallback on builtin code: " OPENCV_HIGHGUI_BUILTIN_BACKEND_STR); + } + else + { + if (!isKnown) + CV_LOG_INFO(NULL, "UI: unknown backend: " << name); + } + g_initializedUIBackend = true; + return std::shared_ptr(); +} + +static inline +std::shared_ptr createDefaultUIBackend() +{ + CV_LOG_DEBUG(NULL, "UI: Initializing backend..."); + return createUIBackend(); +} + +std::shared_ptr& getCurrentUIBackend() +{ + static std::shared_ptr g_currentUIBackend = createDefaultUIBackend(); + return g_currentUIBackend; +} + +void setUIBackend(const std::shared_ptr& api) +{ + getCurrentUIBackend() = api; +} + +bool setUIBackend(const std::string& backendName) +{ + CV_TRACE_FUNCTION(); + + std::string backendName_u = toUpperCase(backendName); + if (g_initializedUIBackend) + { + // ... already initialized + if (getUIBackendName() == backendName_u) + { + CV_LOG_INFO(NULL, "UI: backend is already activated: " << (backendName.empty() ? "builtin(legacy)" : backendName)); + return true; + } + else + { + // ... re-create new + CV_LOG_DEBUG(NULL, "UI: replacing backend..."); + getUIBackendName() = backendName_u; + getCurrentUIBackend() = createUIBackend(); + } + } + else + { + // ... no backend exists, just specify the name (initialization is triggered by getCurrentUIBackend() call) + getUIBackendName() = backendName_u; + } + std::shared_ptr api = getCurrentUIBackend(); + if (!api) + { + if (!backendName.empty()) + { + CV_LOG_WARNING(NULL, "UI: backend is not available: " << backendName << " (using builtin legacy code)"); + return false; + } + else + { + CV_LOG_WARNING(NULL, "UI: switched to builtin code (legacy)"); + } + } + if (!backendName_u.empty()) + { + CV_Assert(backendName_u == getUIBackendName()); // data race? + } + return true; +} + +}} // namespace cv::highgui_backend diff --git a/modules/highgui/src/backend.hpp b/modules/highgui/src/backend.hpp new file mode 100644 index 000000000000..7c32846ce4a3 --- /dev/null +++ b/modules/highgui/src/backend.hpp @@ -0,0 +1,135 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +#ifndef OPENCV_HIGHGUI_BACKEND_HPP +#define OPENCV_HIGHGUI_BACKEND_HPP + +#include +#include + +namespace cv { namespace highgui_backend { + +class CV_EXPORTS UIWindowBase +{ +public: + typedef std::shared_ptr Ptr; + typedef std::weak_ptr WeakPtr; + + virtual ~UIWindowBase(); + + virtual const std::string& getID() const = 0; // internal name, used for logging + + virtual bool isActive() const = 0; + + virtual void destroy() = 0; +}; // UIWindowBase + +class UITrackbar; + +class CV_EXPORTS UIWindow : public UIWindowBase +{ +public: + virtual ~UIWindow(); + + virtual void imshow(InputArray image) = 0; + + virtual double getProperty(int prop) const = 0; + virtual bool setProperty(int prop, double value) = 0; + + virtual void resize(int width, int height) = 0; + virtual void move(int x, int y) = 0; + + virtual Rect getImageRect() const = 0; + + virtual void setTitle(const std::string& title) = 0; + + virtual void setMouseCallback(MouseCallback onMouse, void* userdata /*= 0*/) = 0; + + //TODO: handle both keys and mouse events (both with mouse coordinates) + //virtual void setInputCallback(InputCallback onInputEvent, void* userdata /*= 0*/) = 0; + + virtual std::shared_ptr createTrackbar( + const std::string& name, + int count, + TrackbarCallback onChange /*= 0*/, + void* userdata /*= 0*/ + ) = 0; + + virtual std::shared_ptr findTrackbar(const std::string& name) = 0; + +#if 0 // QT only + virtual void displayOverlay(const std::string& text, int delayms = 0) = 0; + virtual void displayStatusBar(const std::string& text, int delayms /*= 0*/) = 0; + virtual int createButton( + const std::string& bar_name, ButtonCallback on_change, + void* userdata = 0, int type /*= QT_PUSH_BUTTON*/, + bool initial_button_state /*= false*/ + ) = 0; + // addText, QtFont stuff +#endif + +#if 0 // OpenGL + virtual void imshow(const ogl::Texture2D& tex) = 0; + virtual void setOpenGlDrawCallback(OpenGlDrawCallback onOpenGlDraw, void* userdata = 0) = 0; + virtual void setOpenGlContext() = 0; + virtual void updateWindow() = 0; +#endif + +}; // UIWindow + + +class CV_EXPORTS UITrackbar : public UIWindowBase +{ +public: + virtual ~UITrackbar(); + + virtual int getPos() const = 0; + virtual void setPos(int pos) = 0; + + virtual cv::Range getRange() const = 0; + virtual void setRange(const cv::Range& range) = 0; +}; // UITrackbar + + +class CV_EXPORTS UIBackend +{ +public: + virtual ~UIBackend(); + + virtual void destroyAllWindows() = 0; + + // namedWindow + virtual std::shared_ptr createWindow( + const std::string& winname, + int flags + ) = 0; + + virtual int waitKeyEx(int delay /*= 0*/) = 0; + virtual int pollKey() = 0; +}; + +std::shared_ptr& getCurrentUIBackend(); +void setUIBackend(const std::shared_ptr& api); +bool setUIBackend(const std::string& backendName); + +#ifndef BUILD_PLUGIN + +#ifdef HAVE_WIN32UI +std::shared_ptr createUIBackendWin32UI(); +#endif + +#ifdef HAVE_GTK +std::shared_ptr createUIBackendGTK(); +#endif + +#if 0 // TODO: defined HAVE_QT +std::shared_ptr createUIBackendQT(); +#endif + +#endif // BUILD_PLUGIN + +} // namespace highgui_backend + +} // namespace cv + +#endif // OPENCV_HIGHGUI_BACKEND_HPP diff --git a/modules/highgui/src/factory.hpp b/modules/highgui/src/factory.hpp new file mode 100644 index 000000000000..c40358bb20c3 --- /dev/null +++ b/modules/highgui/src/factory.hpp @@ -0,0 +1,48 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_UI_FACTORY_HPP +#define OPENCV_UI_FACTORY_HPP + +#include "backend.hpp" + +namespace cv { namespace highgui_backend { + +class IUIBackendFactory +{ +public: + virtual ~IUIBackendFactory() {} + virtual std::shared_ptr create() const = 0; +}; + + +class StaticBackendFactory CV_FINAL: public IUIBackendFactory +{ +protected: + std::function(void)> create_fn_; + +public: + StaticBackendFactory(std::function(void)>&& create_fn) + : create_fn_(create_fn) + { + // nothing + } + + ~StaticBackendFactory() CV_OVERRIDE {} + + std::shared_ptr create() const CV_OVERRIDE + { + return create_fn_(); + } +}; + +// +// PluginUIBackendFactory is implemented in plugin_wrapper +// + +std::shared_ptr createPluginUIBackendFactory(const std::string& baseName); + +}} // namespace + +#endif // OPENCV_UI_FACTORY_HPP diff --git a/modules/highgui/src/plugin_api.hpp b/modules/highgui/src/plugin_api.hpp new file mode 100644 index 000000000000..fb57b7593e71 --- /dev/null +++ b/modules/highgui/src/plugin_api.hpp @@ -0,0 +1,72 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef UI_PLUGIN_API_HPP +#define UI_PLUGIN_API_HPP + +#include +#include + +#include "backend.hpp" + +#if !defined(BUILD_PLUGIN) + +/// increased for backward-compatible changes, e.g. add new function +/// Caller API <= Plugin API -> plugin is fully compatible +/// Caller API > Plugin API -> plugin is not fully compatible, caller should use extra checks to use plugins with older API +#define API_VERSION 0 // preview + +/// increased for incompatible changes, e.g. remove function argument +/// Caller ABI == Plugin ABI -> plugin is compatible +/// Caller ABI > Plugin ABI -> plugin is not compatible, caller should use shim code to use old ABI plugins (caller may know how lower ABI works, so it is possible) +/// Caller ABI < Plugin ABI -> plugin can't be used (plugin should provide interface with lower ABI to handle that) +#define ABI_VERSION 0 // preview + +#else // !defined(BUILD_PLUGIN) + +#if !defined(ABI_VERSION) || !defined(API_VERSION) +#error "Plugin must define ABI_VERSION and API_VERSION before including plugin_api.hpp" +#endif + +#endif // !defined(BUILD_PLUGIN) + +typedef cv::highgui_backend::UIBackend* CvPluginUIBackend; + +struct OpenCV_UI_Plugin_API_v0_0_api_entries +{ + /** @brief Get backend API instance + + @param[out] handle pointer on backend API handle + + @note API-CALL 1, API-Version == 0 + */ + CvResult (CV_API_CALL *getInstance)(CV_OUT CvPluginUIBackend* handle) CV_NOEXCEPT; +}; // OpenCV_UI_Plugin_API_v0_0_api_entries + +typedef struct OpenCV_UI_Plugin_API_v0 +{ + OpenCV_API_Header api_header; + struct OpenCV_UI_Plugin_API_v0_0_api_entries v0; +} OpenCV_UI_Plugin_API_v0; + +#if ABI_VERSION == 0 && API_VERSION == 0 +typedef OpenCV_UI_Plugin_API_v0 OpenCV_UI_Plugin_API; +#else +#error "Not supported configuration: check ABI_VERSION/API_VERSION" +#endif + +#ifdef BUILD_PLUGIN +extern "C" { + +CV_PLUGIN_EXPORTS +const OpenCV_UI_Plugin_API* CV_API_CALL opencv_ui_plugin_init_v0 + (int requested_abi_version, int requested_api_version, void* reserved /*NULL*/) CV_NOEXCEPT; + +} // extern "C" +#else // BUILD_PLUGIN +typedef const OpenCV_UI_Plugin_API* (CV_API_CALL *FN_opencv_ui_plugin_init_t) + (int requested_abi_version, int requested_api_version, void* reserved /*NULL*/); +#endif // BUILD_PLUGIN + +#endif // UI_PLUGIN_API_HPP diff --git a/modules/highgui/src/plugin_wrapper.impl.hpp b/modules/highgui/src/plugin_wrapper.impl.hpp new file mode 100644 index 000000000000..97aea69098cb --- /dev/null +++ b/modules/highgui/src/plugin_wrapper.impl.hpp @@ -0,0 +1,288 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +// +// Not a standalone header, part of backend.cpp +// + +//================================================================================================== +// Dynamic backend implementation + +#include "opencv2/core/utils/plugin_loader.private.hpp" + +namespace cv { namespace impl { + +using namespace cv::highgui_backend; + +#if OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS) + +using namespace cv::plugin::impl; // plugin_loader.hpp + +class PluginUIBackend CV_FINAL: public std::enable_shared_from_this +{ +protected: + void initPluginAPI() + { + const char* init_name = "opencv_ui_plugin_init_v0"; + FN_opencv_ui_plugin_init_t fn_init = reinterpret_cast(lib_->getSymbol(init_name)); + if (fn_init) + { + CV_LOG_DEBUG(NULL, "Found entry: '" << init_name << "'"); + for (int supported_api_version = API_VERSION; supported_api_version >= 0; supported_api_version--) + { + plugin_api_ = fn_init(ABI_VERSION, supported_api_version, NULL); + if (plugin_api_) + break; + } + if (!plugin_api_) + { + CV_LOG_INFO(NULL, "UI: plugin is incompatible (can't be initialized): " << lib_->getName()); + return; + } + // NB: force strict minor version check (ABI is not preserved for now) + if (!checkCompatibility(plugin_api_->api_header, ABI_VERSION, API_VERSION, true)) + { + plugin_api_ = NULL; + return; + } + CV_LOG_INFO(NULL, "UI: plugin is ready to use '" << plugin_api_->api_header.api_description << "'"); + } + else + { + CV_LOG_INFO(NULL, "UI: plugin is incompatible, missing init function: '" << init_name << "', file: " << lib_->getName()); + } + } + + + bool checkCompatibility(const OpenCV_API_Header& api_header, unsigned int abi_version, unsigned int api_version, bool checkMinorOpenCVVersion) + { + if (api_header.opencv_version_major != CV_VERSION_MAJOR) + { + CV_LOG_ERROR(NULL, "UI: wrong OpenCV major version used by plugin '" << api_header.api_description << "': " << + cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", api_header.opencv_version_major, api_header.opencv_version_minor)) + return false; + } + if (!checkMinorOpenCVVersion) + { + // no checks for OpenCV minor version + } + else if (api_header.opencv_version_minor != CV_VERSION_MINOR) + { + CV_LOG_ERROR(NULL, "UI: wrong OpenCV minor version used by plugin '" << api_header.api_description << "': " << + cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", api_header.opencv_version_major, api_header.opencv_version_minor)) + return false; + } + CV_LOG_DEBUG(NULL, "UI: initialized '" << api_header.api_description << "': built with " + << cv::format("OpenCV %d.%d (ABI/API = %d/%d)", + api_header.opencv_version_major, api_header.opencv_version_minor, + api_header.min_api_version, api_header.api_version) + << ", current OpenCV version is '" CV_VERSION "' (ABI/API = " << abi_version << "/" << api_version << ")" + ); + if (api_header.min_api_version != abi_version) // future: range can be here + { + // actually this should never happen due to checks in plugin's init() function + CV_LOG_ERROR(NULL, "UI: plugin is not supported due to incompatible ABI = " << api_header.min_api_version); + return false; + } + if (api_header.api_version != api_version) + { + CV_LOG_INFO(NULL, "UI: NOTE: plugin is supported, but there is API version mismath: " + << cv::format("plugin API level (%d) != OpenCV API level (%d)", api_header.api_version, api_version)); + if (api_header.api_version < api_version) + { + CV_LOG_INFO(NULL, "UI: NOTE: some functionality may be unavailable due to lack of support by plugin implementation"); + } + } + return true; + } + +public: + std::shared_ptr lib_; + const OpenCV_UI_Plugin_API* plugin_api_; + + PluginUIBackend(const std::shared_ptr& lib) + : lib_(lib) + , plugin_api_(NULL) + { + initPluginAPI(); + } + + std::shared_ptr create() const + { + CV_Assert(plugin_api_); + + CvPluginUIBackend instancePtr = NULL; + + if (plugin_api_->v0.getInstance) + { + if (CV_ERROR_OK == plugin_api_->v0.getInstance(&instancePtr)) + { + CV_Assert(instancePtr); + // TODO C++20 "aliasing constructor" + return std::shared_ptr(instancePtr, [](cv::highgui_backend::UIBackend*){}); // empty deleter + } + } + return std::shared_ptr(); + } +}; + + +class PluginUIBackendFactory CV_FINAL: public IUIBackendFactory +{ +public: + std::string baseName_; + std::shared_ptr backend; + bool initialized; +public: + PluginUIBackendFactory(const std::string& baseName) + : baseName_(baseName) + , initialized(false) + { + // nothing, plugins are loaded on demand + } + + std::shared_ptr create() const CV_OVERRIDE + { + if (!initialized) + { + const_cast(this)->initBackend(); + } + if (backend) + return backend->create(); + return std::shared_ptr(); + } +protected: + void initBackend() + { + AutoLock lock(getInitializationMutex()); + try + { + if (!initialized) + loadPlugin(); + } + catch (...) + { + CV_LOG_INFO(NULL, "UI: exception during plugin loading: " << baseName_ << ". SKIP"); + } + initialized = true; + } + void loadPlugin(); +}; + +static +std::vector getPluginCandidates(const std::string& baseName) +{ + using namespace cv::utils; + using namespace cv::utils::fs; + const std::string baseName_l = toLowerCase(baseName); + const std::string baseName_u = toUpperCase(baseName); + const FileSystemPath_t baseName_l_fs = toFileSystemPath(baseName_l); + std::vector paths; + // TODO OPENCV_PLUGIN_PATH + const std::vector paths_ = getConfigurationParameterPaths("OPENCV_CORE_PLUGIN_PATH", std::vector()); + if (paths_.size() != 0) + { + for (size_t i = 0; i < paths_.size(); i++) + { + paths.push_back(toFileSystemPath(paths_[i])); + } + } + else + { + FileSystemPath_t binaryLocation; + if (getBinLocation(binaryLocation)) + { + binaryLocation = getParent(binaryLocation); +#ifndef CV_UI_PLUGIN_SUBDIRECTORY + paths.push_back(binaryLocation); +#else + paths.push_back(binaryLocation + toFileSystemPath("/") + toFileSystemPath(CV_UI_PLUGIN_SUBDIRECTORY_STR)); +#endif + } + } + const std::string default_expr = libraryPrefix() + "opencv_highgui_" + baseName_l + "*" + librarySuffix(); + const std::string plugin_expr = getConfigurationParameterString((std::string("OPENCV_UI_PLUGIN_") + baseName_u).c_str(), default_expr.c_str()); + std::vector results; +#ifdef _WIN32 + FileSystemPath_t moduleName = toFileSystemPath(libraryPrefix() + "opencv_highgui_" + baseName_l + librarySuffix()); + if (plugin_expr != default_expr) + { + moduleName = toFileSystemPath(plugin_expr); + results.push_back(moduleName); + } + for (const FileSystemPath_t& path : paths) + { + results.push_back(path + L"\\" + moduleName); + } + results.push_back(moduleName); +#else + CV_LOG_DEBUG(NULL, "UI: " << baseName << " plugin's glob is '" << plugin_expr << "', " << paths.size() << " location(s)"); + for (const std::string& path : paths) + { + if (path.empty()) + continue; + std::vector candidates; + cv::glob(utils::fs::join(path, plugin_expr), candidates); + CV_LOG_DEBUG(NULL, " - " << path << ": " << candidates.size()); + copy(candidates.begin(), candidates.end(), back_inserter(results)); + } +#endif + CV_LOG_DEBUG(NULL, "Found " << results.size() << " plugin(s) for " << baseName); + return results; +} + +// NB: require loading of imgcodecs module +static void* g_imwrite = (void*)imwrite; + +void PluginUIBackendFactory::loadPlugin() +{ + CV_Assert(g_imwrite); + for (const FileSystemPath_t& plugin : getPluginCandidates(baseName_)) + { + auto lib = std::make_shared(plugin); + if (!lib->isLoaded()) + { + continue; + } + try + { + auto pluginBackend = std::make_shared(lib); + if (!pluginBackend) + { + continue; + } + if (pluginBackend->plugin_api_ == NULL) + { + CV_LOG_ERROR(NULL, "UI: no compatible plugin API for backend: " << baseName_ << " in " << toPrintablePath(plugin)); + continue; + } + // NB: we are going to use UI backend, so prevent automatic library unloading + lib->disableAutomaticLibraryUnloading(); + backend = pluginBackend; + return; + } + catch (...) + { + CV_LOG_WARNING(NULL, "UI: exception during plugin initialization: " << toPrintablePath(plugin) << ". SKIP"); + } + } +} + +#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS) + +} // namespace + +namespace highgui_backend { + +std::shared_ptr createPluginUIBackendFactory(const std::string& baseName) +{ +#if OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS) + return std::make_shared(baseName); +#else + CV_UNUSED(baseName); + return std::shared_ptr(); +#endif +} + +}} // namespace diff --git a/modules/highgui/src/precomp.hpp b/modules/highgui/src/precomp.hpp index a5b176c9dd91..0d26b957ad71 100644 --- a/modules/highgui/src/precomp.hpp +++ b/modules/highgui/src/precomp.hpp @@ -42,10 +42,19 @@ #ifndef __HIGHGUI_H_ #define __HIGHGUI_H_ +#if defined(__OPENCV_BUILD) && defined(BUILD_PLUGIN) +#undef __OPENCV_BUILD // allow public API only +#endif + #include "opencv2/highgui.hpp" +#if !defined(BUILD_PLUGIN) +#include "opencv_highgui_config.hpp" // generated by CMake +#endif #include "opencv2/core/utility.hpp" +#if defined(__OPENCV_BUILD) #include "opencv2/core/private.hpp" +#endif #include "opencv2/imgproc.hpp" #include "opencv2/imgproc/imgproc_c.h" @@ -58,7 +67,6 @@ #include #include #include -#include #if defined _WIN32 || defined WINCE #include @@ -118,6 +126,13 @@ void cvSetPropTopmost_COCOA(const char* name, const bool topmost); double cvGetPropVsync_W32(const char* name); void cvSetPropVsync_W32(const char* name, const bool enabled); +void setWindowTitle_W32(const cv::String& name, const cv::String& title); +void setWindowTitle_GTK(const cv::String& name, const cv::String& title); +void setWindowTitle_QT(const cv::String& name, const cv::String& title); +void setWindowTitle_COCOA(const cv::String& name, const cv::String& title); + +int pollKey_W32(); + //for QT #if defined (HAVE_QT) CvRect cvGetWindowRect_QT(const char* name); @@ -169,4 +184,11 @@ inline void convertToShow(const cv::Mat &src, const CvMat* arr, bool toRGB = tru } +namespace cv { + +CV_EXPORTS Mutex& getWindowMutex(); +static inline Mutex& getInitializationMutex() { return getWindowMutex(); } + +} // namespace + #endif /* __HIGHGUI_H_ */ diff --git a/modules/highgui/src/registry.hpp b/modules/highgui/src/registry.hpp new file mode 100644 index 000000000000..77c1234f0544 --- /dev/null +++ b/modules/highgui/src/registry.hpp @@ -0,0 +1,25 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_HIGHGUI_REGISTRY_HPP +#define OPENCV_HIGHGUI_REGISTRY_HPP + +#include "factory.hpp" + +namespace cv { namespace highgui_backend { + +struct BackendInfo +{ + int priority; // 1000- - default builtin priority + // 0 - disabled (OPENCV_UI_PRIORITY_ = 0) + // >10000 - prioritized list (OPENCV_UI_PRIORITY_LIST) + std::string name; + std::shared_ptr backendFactory; +}; + +const std::vector& getBackendsInfo(); + +}} // namespace + +#endif // OPENCV_HIGHGUI_REGISTRY_HPP diff --git a/modules/highgui/src/registry.impl.hpp b/modules/highgui/src/registry.impl.hpp new file mode 100644 index 000000000000..66693f1b07e0 --- /dev/null +++ b/modules/highgui/src/registry.impl.hpp @@ -0,0 +1,194 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +// +// Not a standalone header, part of backend.cpp +// + +#include "opencv2/core/utils/filesystem.private.hpp" // OPENCV_HAVE_FILESYSTEM_SUPPORT + +namespace cv { namespace highgui_backend { + +#if OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS) +#define DECLARE_DYNAMIC_BACKEND(name) \ +BackendInfo { \ + 1000, name, createPluginUIBackendFactory(name) \ +}, +#else +#define DECLARE_DYNAMIC_BACKEND(name) /* nothing */ +#endif + +#define DECLARE_STATIC_BACKEND(name, createBackendAPI) \ +BackendInfo { \ + 1000, name, std::make_shared([=] () -> std::shared_ptr { return createBackendAPI(); }) \ +}, + +static +std::vector& getBuiltinBackendsInfo() +{ + static std::vector g_backends + { +#ifdef HAVE_GTK + DECLARE_STATIC_BACKEND("GTK", createUIBackendGTK) +#if defined(HAVE_GTK3) + DECLARE_STATIC_BACKEND("GTK3", createUIBackendGTK) +#elif defined(HAVE_GTK2) + DECLARE_STATIC_BACKEND("GTK2", createUIBackendGTK) +#else +#warning "HAVE_GTK definition issue. Register new GTK backend" +#endif +#elif defined(ENABLE_PLUGINS) + DECLARE_DYNAMIC_BACKEND("GTK") + DECLARE_DYNAMIC_BACKEND("GTK3") + DECLARE_DYNAMIC_BACKEND("GTK2") +#endif + +#if 0 // TODO +#ifdef HAVE_QT + DECLARE_STATIC_BACKEND("QT", createUIBackendQT) +#elif defined(ENABLE_PLUGINS) + DECLARE_DYNAMIC_BACKEND("QT") +#endif +#endif + +#ifdef _WIN32 +#ifdef HAVE_WIN32UI + DECLARE_STATIC_BACKEND("WIN32", createUIBackendWin32UI) +#elif defined(ENABLE_PLUGINS) + DECLARE_DYNAMIC_BACKEND("WIN32") +#endif +#endif + }; + return g_backends; +}; + +static +bool sortByPriority(const BackendInfo &lhs, const BackendInfo &rhs) +{ + return lhs.priority > rhs.priority; +} + +/** @brief Manages list of enabled backends + */ +class UIBackendRegistry +{ +protected: + std::vector enabledBackends; + UIBackendRegistry() + { + enabledBackends = getBuiltinBackendsInfo(); + int N = (int)enabledBackends.size(); + for (int i = 0; i < N; i++) + { + BackendInfo& info = enabledBackends[i]; + info.priority = 1000 - i * 10; + } + CV_LOG_DEBUG(NULL, "UI: Builtin backends(" << N << "): " << dumpBackends()); + if (readPrioritySettings()) + { + CV_LOG_INFO(NULL, "UI: Updated backends priorities: " << dumpBackends()); + N = (int)enabledBackends.size(); + } + int enabled = 0; + for (int i = 0; i < N; i++) + { + BackendInfo& info = enabledBackends[enabled]; + if (enabled != i) + info = enabledBackends[i]; + size_t param_priority = utils::getConfigurationParameterSizeT(cv::format("OPENCV_UI_PRIORITY_%s", info.name.c_str()).c_str(), (size_t)info.priority); + CV_Assert(param_priority == (size_t)(int)param_priority); // overflow check + if (param_priority > 0) + { + info.priority = (int)param_priority; + enabled++; + } + else + { + CV_LOG_INFO(NULL, "UI: Disable backend: " << info.name); + } + } + enabledBackends.resize(enabled); + CV_LOG_DEBUG(NULL, "UI: Available backends(" << enabled << "): " << dumpBackends()); + std::sort(enabledBackends.begin(), enabledBackends.end(), sortByPriority); + CV_LOG_INFO(NULL, "UI: Enabled backends(" << enabled << ", sorted by priority): " << (enabledBackends.empty() ? std::string("N/A") : dumpBackends())); + } + + static std::vector tokenize_string(const std::string& input, char token) + { + std::vector result; + std::string::size_type prev_pos = 0, pos = 0; + while((pos = input.find(token, pos)) != std::string::npos) + { + result.push_back(input.substr(prev_pos, pos-prev_pos)); + prev_pos = ++pos; + } + result.push_back(input.substr(prev_pos)); + return result; + } + bool readPrioritySettings() + { + bool hasChanges = false; + cv::String prioritized_backends = utils::getConfigurationParameterString("OPENCV_UI_PRIORITY_LIST", NULL); + if (prioritized_backends.empty()) + return hasChanges; + CV_LOG_INFO(NULL, "UI: Configured priority list (OPENCV_UI_PRIORITY_LIST): " << prioritized_backends); + const std::vector names = tokenize_string(prioritized_backends, ','); + for (size_t i = 0; i < names.size(); i++) + { + const std::string& name = names[i]; + int priority = (int)(100000 + (names.size() - i) * 1000); + bool found = false; + for (size_t k = 0; k < enabledBackends.size(); k++) + { + BackendInfo& info = enabledBackends[k]; + if (name == info.name) + { + info.priority = priority; + CV_LOG_DEBUG(NULL, "UI: New backend priority: '" << name << "' => " << info.priority); + found = true; + hasChanges = true; + break; + } + } + if (!found) + { + CV_LOG_INFO(NULL, "UI: Adding backend (plugin): '" << name << "'"); + enabledBackends.push_back(BackendInfo{priority, name, createPluginUIBackendFactory(name)}); + hasChanges = true; + } + } + return hasChanges; + } +public: + std::string dumpBackends() const + { + std::ostringstream os; + for (size_t i = 0; i < enabledBackends.size(); i++) + { + if (i > 0) os << "; "; + const BackendInfo& info = enabledBackends[i]; + os << info.name << '(' << info.priority << ')'; + } +#if !defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) + os << " + BUILTIN(" OPENCV_HIGHGUI_BUILTIN_BACKEND_STR ")"; +#endif + return os.str(); + } + + static UIBackendRegistry& getInstance() + { + static UIBackendRegistry g_instance; + return g_instance; + } + + inline const std::vector& getEnabledBackends() const { return enabledBackends; } +}; + + +const std::vector& getBackendsInfo() +{ + return cv::highgui_backend::UIBackendRegistry::getInstance().getEnabledBackends(); +} + +}} // namespace diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index d2cf1e1e4826..d9481de6da24 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -40,20 +40,186 @@ //M*/ #include "precomp.hpp" -#include +#include "backend.hpp" + #include "opencv2/core/opengl.hpp" #include "opencv2/core/utils/logger.hpp" // in later times, use this file as a dispatcher to implementations like cvcap.cpp + +using namespace cv; +using namespace cv::highgui_backend; + +namespace cv { + +Mutex& getWindowMutex() +{ + static Mutex* g_window_mutex = new Mutex(); + return *g_window_mutex; +} + +namespace impl { + +typedef std::map WindowsMap_t; +static WindowsMap_t& getWindowsMap() +{ + static WindowsMap_t g_windowsMap; + return g_windowsMap; +} + +static std::shared_ptr findWindow_(const std::string& name) +{ + cv::AutoLock lock(cv::getWindowMutex()); + auto& windowsMap = getWindowsMap(); + auto i = windowsMap.find(name); + if (i != windowsMap.end()) + { + const auto& ui_base = i->second; + if (ui_base) + { + if (!ui_base->isActive()) + { + windowsMap.erase(i); + return std::shared_ptr(); + } + auto window = std::dynamic_pointer_cast(ui_base); + return window; + } + } + return std::shared_ptr(); +} + +static void cleanupTrackbarCallbacksWithData_(); // forward declaration + +static void cleanupClosedWindows_() +{ + cv::AutoLock lock(cv::getWindowMutex()); + auto& windowsMap = getWindowsMap(); + for (auto it = windowsMap.begin(); it != windowsMap.end();) + { + const auto& ui_base = it->second; + bool erase = (!ui_base || !ui_base->isActive()); + if (erase) + { + it = windowsMap.erase(it); + } + else + { + ++it; + } + } + + cleanupTrackbarCallbacksWithData_(); +} + +// Just to support deprecated API, to be removed +struct TrackbarCallbackWithData +{ + std::weak_ptr trackbar_; + int* data_; + TrackbarCallback callback_; + void* userdata_; + + TrackbarCallbackWithData(int* data, TrackbarCallback callback, void* userdata) + : data_(data) + , callback_(callback), userdata_(userdata) + { + // trackbar_ is initialized separatelly + } + + ~TrackbarCallbackWithData() + { + CV_LOG_DEBUG(NULL, "UI/Trackbar: Cleanup deprecated TrackbarCallbackWithData"); + } + + void onChange(int pos) + { + if (data_) + *data_ = pos; + if (callback_) + callback_(pos, userdata_); + } + + static void onChangeCallback(int pos, void* userdata) + { + TrackbarCallbackWithData* thiz = (TrackbarCallbackWithData*)userdata; + CV_Assert(thiz); + return thiz->onChange(pos); + } +}; + +typedef std::vector< std::shared_ptr > TrackbarCallbacksWithData_t; +static TrackbarCallbacksWithData_t& getTrackbarCallbacksWithData() +{ + static TrackbarCallbacksWithData_t g_trackbarCallbacksWithData; + return g_trackbarCallbacksWithData; +} + +static void cleanupTrackbarCallbacksWithData_() +{ + cv::AutoLock lock(cv::getWindowMutex()); + auto& callbacks = getTrackbarCallbacksWithData(); + for (auto it = callbacks.begin(); it != callbacks.end();) + { + const auto& cb = *it; + bool erase = (!cb || cb->trackbar_.expired()); + if (erase) + { + it = callbacks.erase(it); + } + else + { + ++it; + } + } +} + +}} // namespace cv::impl + +using namespace cv::impl; + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) +static void deprecateNotFoundNoOpBehavior() +{ + CV_LOG_ONCE_WARNING(NULL, "This no-op behavior is deprecated. Future versions of OpenCV will trigger exception in this case"); +} +#define CV_NOT_FOUND_DEPRECATION deprecateNotFoundNoOpBehavior() +#endif + CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_value) { + CV_TRACE_FUNCTION(); + CV_Assert(name); + + { + auto window = findWindow_(name); + if (window) + { + /*bool res = */window->setProperty(prop_id, prop_value); + return; + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << name << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else switch(prop_id) { //change between fullscreen or not. case CV_WND_PROP_FULLSCREEN: - if (!name || (prop_value!=CV_WINDOW_NORMAL && prop_value!=CV_WINDOW_FULLSCREEN))//bad argument + if (prop_value != CV_WINDOW_NORMAL && prop_value != CV_WINDOW_FULLSCREEN) // bad argument break; #if defined (HAVE_QT) @@ -104,14 +270,39 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu default:; } +#endif } /* return -1 if error */ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) { - if (!name) - return -1; + CV_TRACE_FUNCTION(); + CV_Assert(name); + + { + auto window = findWindow_(name); + if (window) + { + double v = window->getProperty(prop_id); + if (cvIsNaN(v)) + return -1; + return v; + } + } +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << name << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return -1; +#else switch(prop_id) { case CV_WND_PROP_FULLSCREEN: @@ -205,12 +396,35 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) default: return -1; } +#endif } cv::Rect cvGetWindowImageRect(const char* name) { - if (!name) - return cv::Rect(-1, -1, -1, -1); + CV_TRACE_FUNCTION(); + CV_Assert(name); + + { + auto window = findWindow_(name); + if (window) + { + return window->getImageRect(); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << name << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return Rect(-1, -1, -1, -1); +#else #if defined (HAVE_QT) return cvGetWindowRect_QT(name); @@ -221,8 +435,10 @@ cv::Rect cvGetWindowImageRect(const char* name) #elif defined (HAVE_COCOA) return cvGetWindowRect_COCOA(name); #else - return cv::Rect(-1, -1, -1, -1); + return Rect(-1, -1, -1, -1); #endif + +#endif } cv::Rect cv::getWindowImageRect(const String& winname) @@ -234,25 +450,105 @@ cv::Rect cv::getWindowImageRect(const String& winname) void cv::namedWindow( const String& winname, int flags ) { CV_TRACE_FUNCTION(); + CV_Assert(!winname.empty()); + + { + cv::AutoLock lock(cv::getWindowMutex()); + cleanupClosedWindows_(); + auto& windowsMap = getWindowsMap(); + auto i = windowsMap.find(winname); + if (i != windowsMap.end()) + { + auto ui_base = i->second; + if (ui_base) + { + auto window = std::dynamic_pointer_cast(ui_base); + if (!window) + { + CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'"); + } + return; + } + } + auto backend = getCurrentUIBackend(); + if (backend) + { + auto window = backend->createWindow(winname, flags); + if (!window) + { + CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'"); + return; + } + windowsMap.emplace(winname, window); + return; + } + } + cvNamedWindow( winname.c_str(), flags ); } void cv::destroyWindow( const String& winname ) { CV_TRACE_FUNCTION(); + + { + auto window = findWindow_(winname); + if (window) + { + window->destroy(); + cleanupClosedWindows_(); + return; + } + } + cvDestroyWindow( winname.c_str() ); } void cv::destroyAllWindows() { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto backend = getCurrentUIBackend(); + if (backend) + { + backend->destroyAllWindows(); + cleanupClosedWindows_(); + return; + } + } + cvDestroyAllWindows(); } void cv::resizeWindow( const String& winname, int width, int height ) { CV_TRACE_FUNCTION(); + + { + auto window = findWindow_(winname); + if (window) + { + return window->resize(width, height); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winname << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else cvResizeWindow( winname.c_str(), width, height ); +#endif } void cv::resizeWindow(const String& winname, const cv::Size& size) @@ -264,7 +560,70 @@ void cv::resizeWindow(const String& winname, const cv::Size& size) void cv::moveWindow( const String& winname, int x, int y ) { CV_TRACE_FUNCTION(); + + { + auto window = findWindow_(winname); + if (window) + { + return window->move(x, y); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winname << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else cvMoveWindow( winname.c_str(), x, y ); +#endif +} + +void cv::setWindowTitle(const String& winname, const String& title) +{ + CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(winname); + if (window) + { + return window->setTitle(title); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winname << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#elif defined(HAVE_WIN32UI) + return setWindowTitle_W32(winname, title); +#elif defined (HAVE_GTK) + return setWindowTitle_GTK(winname, title); +#elif defined (HAVE_QT) + return setWindowTitle_QT(winname, title); +#elif defined (HAVE_COCOA) + return setWindowTitle_COCOA(winname, title); +#else + CV_Error(Error::StsNotImplemented, "The function is not implemented. " + "Rebuild the library with Windows, GTK+ 2.x or Cocoa support. " + "If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script"); +#endif } void cv::setWindowProperty(const String& winname, int prop_id, double prop_value) @@ -282,6 +641,16 @@ double cv::getWindowProperty(const String& winname, int prop_id) int cv::waitKeyEx(int delay) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto backend = getCurrentUIBackend(); + if (backend) + { + return backend->waitKeyEx(delay); + } + } + return cvWaitKey(delay); } @@ -301,55 +670,251 @@ int cv::waitKey(int delay) return (code != -1) ? (code & 0xff) : -1; } -#if defined(HAVE_WIN32UI) -// pollKey() implemented in window_w32.cpp -#elif defined(HAVE_GTK) || defined(HAVE_COCOA) || defined(HAVE_QT) || (defined (WINRT) && !defined (WINRT_8_0)) -// pollKey() fallback implementation +/* + * process until queue is empty but don't wait. + */ int cv::pollKey() { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto backend = getCurrentUIBackend(); + if (backend) + { + return backend->pollKey(); + } + } + +#if defined(HAVE_WIN32UI) + return pollKey_W32(); +#else // fallback. please implement a proper polling function return cvWaitKey(1); -} #endif +} int cv::createTrackbar(const String& trackbarName, const String& winName, int* value, int count, TrackbarCallback callback, void* userdata) { CV_TRACE_FUNCTION(); + + CV_LOG_IF_WARNING(NULL, value, "UI/Trackbar(" << trackbarName << "@" << winName << "): Using 'value' pointer is unsafe and deprecated. Use NULL as value pointer. " + "To fetch trackbar value setup callback."); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(winName); + if (window) + { + if (value) + { + auto cb = std::make_shared(value, callback, userdata); + auto trackbar = window->createTrackbar(trackbarName, count, TrackbarCallbackWithData::onChangeCallback, cb.get()); + if (!trackbar) + { + CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create trackbar: '" << trackbarName << "'@'" << winName << "'"); + return 0; + } + cb->trackbar_ = trackbar; + getTrackbarCallbacksWithData().emplace_back(cb); + getWindowsMap().emplace(trackbar->getID(), trackbar); + trackbar->setPos(*value); + return 1; + } + else + { + auto trackbar = window->createTrackbar(trackbarName, count, callback, userdata); + if (!trackbar) + { + CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create trackbar: '" << trackbarName << "'@'" << winName << "'"); + return 0; + } + getWindowsMap().emplace(trackbar->getID(), trackbar); + return 1; + } + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return 0; +#else return cvCreateTrackbar2(trackbarName.c_str(), winName.c_str(), value, count, callback, userdata); +#endif } void cv::setTrackbarPos( const String& trackbarName, const String& winName, int value ) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(winName); + if (window) + { + auto trackbar = window->findTrackbar(trackbarName); + CV_Assert(trackbar); + return trackbar->setPos(value); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else cvSetTrackbarPos(trackbarName.c_str(), winName.c_str(), value ); +#endif } void cv::setTrackbarMax(const String& trackbarName, const String& winName, int maxval) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(winName); + if (window) + { + auto trackbar = window->findTrackbar(trackbarName); + CV_Assert(trackbar); + Range old_range = trackbar->getRange(); + Range range(std::min(old_range.start, maxval), maxval); + return trackbar->setRange(range); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else cvSetTrackbarMax(trackbarName.c_str(), winName.c_str(), maxval); +#endif } void cv::setTrackbarMin(const String& trackbarName, const String& winName, int minval) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(winName); + if (window) + { + auto trackbar = window->findTrackbar(trackbarName); + CV_Assert(trackbar); + Range old_range = trackbar->getRange(); + Range range(minval, std::max(minval, old_range.end)); + return trackbar->setRange(range); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else cvSetTrackbarMin(trackbarName.c_str(), winName.c_str(), minval); +#endif } int cv::getTrackbarPos( const String& trackbarName, const String& winName ) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(winName); + if (window) + { + auto trackbar = window->findTrackbar(trackbarName); + CV_Assert(trackbar); + return trackbar->getPos(); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << winName << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return -1; +#else return cvGetTrackbarPos(trackbarName.c_str(), winName.c_str()); +#endif } void cv::setMouseCallback( const String& windowName, MouseCallback onMouse, void* param) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + auto window = findWindow_(windowName); + if (window) + { + return window->setMouseCallback(onMouse, param); + } + } + +#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS) + auto backend = getCurrentUIBackend(); + if (backend) + { + CV_LOG_WARNING(NULL, "Can't find window with name: '" << windowName << "'. Do nothing"); + CV_NOT_FOUND_DEPRECATION; + } + else + { + CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation"); + } + return; +#else cvSetMouseCallback(windowName.c_str(), onMouse, param); +#endif } int cv::getMouseWheelDelta( int flags ) @@ -403,6 +968,39 @@ namespace void cv::imshow( const String& winname, InputArray _img ) { CV_TRACE_FUNCTION(); + + { + cv::AutoLock lock(cv::getWindowMutex()); + cleanupClosedWindows_(); + auto& windowsMap = getWindowsMap(); + auto i = windowsMap.find(winname); + if (i != windowsMap.end()) + { + auto ui_base = i->second; + if (ui_base) + { + auto window = std::dynamic_pointer_cast(ui_base); + if (!window) + { + CV_LOG_ERROR(NULL, "OpenCV/UI: invalid window name: '" << winname << "'"); + } + return window->imshow(_img); + } + } + auto backend = getCurrentUIBackend(); + if (backend) + { + auto window = backend->createWindow(winname, WINDOW_AUTOSIZE); + if (!window) + { + CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'"); + return; + } + windowsMap.emplace(winname, window); + return window->imshow(_img); + } + } + const Size size = _img.size(); #ifndef HAVE_OPENGL CV_Assert(size.width>0 && size.height>0); @@ -646,13 +1244,6 @@ int cv::createButton(const String&, ButtonCallback, void*, int , bool ) // version with a more capable one without a need to recompile dependent // applications or libraries. -void cv::setWindowTitle(const String&, const String&) -{ - CV_Error(Error::StsNotImplemented, "The function is not implemented. " - "Rebuild the library with Windows, GTK+ 2.x or Cocoa support. " - "If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script"); -} - #define CV_NO_GUI_ERROR(funcname) \ cv::error(cv::Error::StsError, \ "The function is not implemented. " \ @@ -803,11 +1394,6 @@ CV_IMPL int cvCreateButton(const char*, void (*)(int, void*), void*, int, int) CV_NO_GUI_ERROR("cvCreateButton"); } -int cv::pollKey() -{ - CV_NO_GUI_ERROR("cv::pollKey()"); -} - #endif /* End of file. */ diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 1600bd917f2b..9899dfdcf0f1 100644 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -63,6 +63,7 @@ #endif #endif +using namespace cv; //Static and global first static GuiReceiver *guiMainThread = NULL; @@ -197,7 +198,7 @@ void cvSetPropWindow_QT(const char* name,double prop_value) Q_ARG(double, prop_value)); } -void cv::setWindowTitle(const String& winname, const String& title) +void setWindowTitle_QT(const String& winname, const String& title) { if (!guiMainThread) CV_Error(Error::StsNullPtr, "NULL guiReceiver (please create a window)"); @@ -1219,9 +1220,6 @@ void GuiReceiver::addSlider2(QString bar_name, QString window_name, void* value, if (t) //trackbar exists return; - if (!value) - CV_Error(CV_StsNullPtr, "NULL value pointer" ); - if (count <= 0) //count is the max value of the slider, so must be bigger than 0 CV_Error(CV_StsNullPtr, "Max value of the slider must be bigger than 0" ); @@ -1342,7 +1340,8 @@ void CvTrackbar::create(CvWindow* arg, QString name, int* value, int _count) slider->setMinimum(0); slider->setMaximum(_count); slider->setPageStep(5); - slider->setValue(*value); + if (dataSlider) + slider->setValue(*dataSlider); slider->setTickPosition(QSlider::TicksBelow); @@ -1409,7 +1408,8 @@ void CvTrackbar::update(int myvalue) { setLabel(myvalue); - *dataSlider = myvalue; + if (dataSlider) + *dataSlider = myvalue; if (callback) { callback(myvalue); diff --git a/modules/highgui/src/window_QT.h b/modules/highgui/src/window_QT.h index dbeacf2edff6..398f3869f88a 100644 --- a/modules/highgui/src/window_QT.h +++ b/modules/highgui/src/window_QT.h @@ -256,7 +256,7 @@ private slots: QPointer label; CvTrackbarCallback callback; CvTrackbarCallback2 callback2;//look like it is use by python binding - int* dataSlider; + int* dataSlider; // deprecated void* userdata; }; diff --git a/modules/highgui/src/window_cocoa.mm b/modules/highgui/src/window_cocoa.mm index 29a0278c982e..e8e903440675 100644 --- a/modules/highgui/src/window_cocoa.mm +++ b/modules/highgui/src/window_cocoa.mm @@ -795,18 +795,18 @@ void cvSetPropTopmost_COCOA( const char* name, const bool topmost ) __END__; } -void cv::setWindowTitle(const String& winname, const String& title) +void setWindowTitle_COCOA(const cv::String& winname, const cv::String& title) { CVWindow *window = cvGetWindow(winname.c_str()); if (window == NULL) { - namedWindow(winname); + cv::namedWindow(winname); window = cvGetWindow(winname.c_str()); } if (window == NULL) - CV_Error(Error::StsNullPtr, "NULL window"); + CV_Error(cv::Error::StsNullPtr, "NULL window"); NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index 073b3404432a..3428586ea344 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -40,12 +40,19 @@ //M*/ #include "precomp.hpp" - -#ifndef _WIN32 +#include "backend.hpp" #if defined (HAVE_GTK) #include + +#if (GTK_MAJOR_VERSION == 3) && defined(HAVE_OPENGL) + #undef HAVE_OPENGL // no support with GTK3 +#endif +#if defined(HAVE_OPENGL) && !defined(HAVE_GTKGLEXT) + #undef HAVE_OPENGL // gtkglext is required +#endif + #include #include #include @@ -104,9 +111,6 @@ struct _CvImageWidgetClass /** Allocate new image viewer widget */ GtkWidget* cvImageWidgetNew (int flags); -/** Set the image to display in the widget */ -void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr); - // standard GTK object macros #define CV_IMAGE_WIDGET(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, cvImageWidget_get_type (), CvImageWidget) #define CV_IMAGE_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cvImageWidget_get_type (), CvImageWidgetClass) @@ -122,7 +126,10 @@ static GtkWidgetClass * parent_class = NULL; // flag to help size initial window #define CV_WINDOW_NO_IMAGE 2 -void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr){ +/** Set the image to display in the widget */ +static +void cvImageWidgetSetImage(CvImageWidget * widget, const CvArr *arr) +{ CvMat * mat, stub; int origin=0; @@ -156,6 +163,7 @@ cvImageWidgetNew (int flags) CvImageWidget *image_widget; image_widget = CV_IMAGE_WIDGET( gtk_widget_new (cvImageWidget_get_type (), NULL) ); + CV_Assert(image_widget && "GTK widget creation is failed. Ensure that there is no GTK2/GTK3 libraries conflict"); image_widget->original_image = 0; image_widget->scaled_image = 0; image_widget->flags = flags | CV_WINDOW_NO_IMAGE; @@ -356,7 +364,7 @@ static void cvImageWidget_set_size(GtkWidget * widget, int max_width, int max_he } - assert( image_widget->scaled_image ); + CV_Assert(image_widget->scaled_image); } static void @@ -522,12 +530,13 @@ struct CvUIBase { struct CvTrackbar : CvUIBase { - CvTrackbar(const char* trackbar_name) : + CvTrackbar(const std::string& trackbar_name) : CvUIBase(CV_TRACKBAR_MAGIC_VAL), widget(NULL), name(trackbar_name), parent(NULL), data(NULL), pos(0), maxval(0), minval(0), - notify(NULL), notify2(NULL), userdata(NULL) + notify(NULL), notify2(NULL), // deprecated + onChangeCallback(NULL), userdata(NULL) { // nothing } @@ -538,20 +547,21 @@ struct CvTrackbar : CvUIBase GtkWidget* widget; std::string name; - CvWindow* parent; + CvWindow* parent; // TODO weak_ptr int* data; int pos; int maxval; int minval; - CvTrackbarCallback notify; - CvTrackbarCallback2 notify2; + CvTrackbarCallback notify; // deprecated + CvTrackbarCallback2 notify2; // deprecated + TrackbarCallback onChangeCallback; void* userdata; }; struct CvWindow : CvUIBase { - CvWindow(const char* window_name) : + CvWindow(const std::string& window_name) : CvUIBase(CV_WINDOW_MAGIC_VAL), widget(NULL), frame(NULL), paned(NULL), name(window_name), last_key(0), flags(0), status(0), @@ -560,9 +570,10 @@ struct CvWindow : CvUIBase ,useGl(false), glDrawCallback(NULL), glDrawData(NULL) #endif { - // nothing + CV_LOG_INFO(NULL, "OpenCV/UI: creating GTK window: " << window_name); } ~CvWindow(); + void destroy(); GtkWidget* widget; GtkWidget* frame; @@ -576,7 +587,7 @@ struct CvWindow : CvUIBase CvMouseCallback on_mouse; void* on_mouse_param; - std::vector< Ptr > trackbars; + std::vector< std::shared_ptr > trackbars; #ifdef HAVE_OPENGL bool useGl; @@ -600,15 +611,15 @@ GCond* cond_have_key = NULL; GThread* window_thread = NULL; #endif -static cv::Mutex& getWindowMutex() +static int last_key = -1; + +static +std::vector< std::shared_ptr >& getGTKWindows() { - static cv::Mutex* g_window_mutex = new cv::Mutex(); - return *g_window_mutex; + static std::vector< std::shared_ptr > g_windows; + return g_windows; } -static int last_key = -1; -static std::vector< Ptr > g_windows; - CV_IMPL int cvInitSystem( int argc, char** argv ) { static int wasInitialized = 0; @@ -700,19 +711,32 @@ gpointer icvWindowThreadLoop(gpointer /*data*/) #define CV_LOCK_MUTEX() cv::AutoLock lock(getWindowMutex()) -static CvWindow* icvFindWindowByName( const char* name ) +static +std::shared_ptr icvFindWindowByName(const std::string& name) { + auto& g_windows = getGTKWindows(); for(size_t i = 0; i < g_windows.size(); ++i) { - CvWindow* window = g_windows[i].get(); + auto window = g_windows[i]; + if (!window) + continue; if (window->name == name) return window; } - return NULL; + return std::shared_ptr(); } +static inline +std::shared_ptr icvFindWindowByName(const char* name) +{ + CV_Assert(name); + return icvFindWindowByName(std::string(name)); +} + + static CvWindow* icvWindowByWidget( GtkWidget* widget ) { + auto& g_windows = getGTKWindows(); for (size_t i = 0; i < g_windows.size(); ++i) { CvWindow* window = g_windows[i].get(); @@ -722,20 +746,29 @@ static CvWindow* icvWindowByWidget( GtkWidget* widget ) return NULL; } +static Rect getImageRect_(const std::shared_ptr& window); + CvRect cvGetWindowRect_GTK(const char* name) { CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + const auto window = icvFindWindowByName(name); if (!window) CV_Error( CV_StsNullPtr, "NULL window" ); + return cvRect(getImageRect_(window)); +} + +static Rect getImageRect_(const std::shared_ptr& window) +{ + CV_Assert(window); + gint wx, wy; #ifdef HAVE_OPENGL if (window->useGl) { gtk_widget_translate_coordinates(window->widget, gtk_widget_get_toplevel(window->widget), 0, 0, &wx, &wy); - return cvRect(wx, wy, window->widget->allocation.width, window->widget->allocation.height); + return Rect(wx, wy, window->widget->allocation.width, window->widget->allocation.height); } #endif @@ -743,23 +776,23 @@ CvRect cvGetWindowRect_GTK(const char* name) gtk_widget_translate_coordinates(&image_widget->widget, gtk_widget_get_toplevel(&image_widget->widget), 0, 0, &wx, &wy); if (image_widget->scaled_image) { #if defined (GTK_VERSION3) - return cvRect(wx, wy, MIN(image_widget->scaled_image->cols, gtk_widget_get_allocated_width(window->widget)), + return Rect(wx, wy, MIN(image_widget->scaled_image->cols, gtk_widget_get_allocated_width(window->widget)), MIN(image_widget->scaled_image->rows, gtk_widget_get_allocated_height(window->widget))); #else - return cvRect(wx, wy, MIN(image_widget->scaled_image->cols, window->widget->allocation.width), + return Rect(wx, wy, MIN(image_widget->scaled_image->cols, window->widget->allocation.width), MIN(image_widget->scaled_image->rows, window->widget->allocation.height)); #endif //GTK_VERSION3 } else if (image_widget->original_image) { #if defined (GTK_VERSION3) - return cvRect(wx, wy, MIN(image_widget->original_image->cols, gtk_widget_get_allocated_width(window->widget)), + return Rect(wx, wy, MIN(image_widget->original_image->cols, gtk_widget_get_allocated_width(window->widget)), MIN(image_widget->original_image->rows, gtk_widget_get_allocated_height(window->widget))); #else - return cvRect(wx, wy, MIN(image_widget->original_image->cols, window->widget->allocation.width), + return Rect(wx, wy, MIN(image_widget->original_image->cols, window->widget->allocation.width), MIN(image_widget->original_image->rows, window->widget->allocation.height)); #endif //GTK_VERSION3 } - return cvRect(-1, -1, -1, -1); + return Rect(-1, -1, -1, -1); } double cvGetModeWindow_GTK(const char* name)//YV @@ -767,7 +800,7 @@ double cvGetModeWindow_GTK(const char* name)//YV CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + const auto window = icvFindWindowByName(name); if (!window) CV_Error( CV_StsNullPtr, "NULL window" ); @@ -775,42 +808,52 @@ double cvGetModeWindow_GTK(const char* name)//YV return result; } - +static bool setModeWindow_(const std::shared_ptr& window, int mode); void cvSetModeWindow_GTK( const char* name, double prop_value)//Yannick Verdie { CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); - if( !window ) + const auto window = icvFindWindowByName(name); + if (!window) CV_Error( CV_StsNullPtr, "NULL window" ); - if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set - return; + setModeWindow_(window, (int)prop_value); +} + +static bool setModeWindow_(const std::shared_ptr& window, int mode) +{ + if (window->flags & CV_WINDOW_AUTOSIZE) //if the flag CV_WINDOW_AUTOSIZE is set + return false; //so easy to do fullscreen here, Linux rocks ! - if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) + if (window->status == mode) + return true; + + if (window->status==CV_WINDOW_FULLSCREEN && mode==CV_WINDOW_NORMAL) { gtk_window_unfullscreen(GTK_WINDOW(window->frame)); window->status=CV_WINDOW_NORMAL; - return; + return true; } - if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) + if (window->status==CV_WINDOW_NORMAL && mode==CV_WINDOW_FULLSCREEN) { gtk_window_fullscreen(GTK_WINDOW(window->frame)); window->status=CV_WINDOW_FULLSCREEN; - return; + return true; } + + return false; } -void cv::setWindowTitle(const String& winname, const String& title) +void setWindowTitle_GTK(const String& winname, const String& title) { CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(winname.c_str()); + auto window = icvFindWindowByName(winname.c_str()); if (!window) { @@ -828,7 +871,7 @@ double cvGetPropWindowAutoSize_GTK(const char* name) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + const auto window = icvFindWindowByName(name); if (!window) return -1; // keep silence here @@ -836,16 +879,22 @@ double cvGetPropWindowAutoSize_GTK(const char* name) return result; } +static double getRatioWindow_(const std::shared_ptr& window); double cvGetRatioWindow_GTK(const char* name) { CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + const auto window = icvFindWindowByName(name); if (!window) return -1; // keep silence here + return getRatioWindow_(window); +} + +static double getRatioWindow_(const std::shared_ptr& window) +{ #if defined (GTK_VERSION3) double result = static_cast( gtk_widget_get_allocated_width(window->widget)) / gtk_widget_get_allocated_height(window->widget); @@ -862,7 +911,7 @@ double cvGetOpenGlProp_GTK(const char* name) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + const auto window = icvFindWindowByName(name); if (!window) return -1; // keep silence here @@ -1048,6 +1097,7 @@ static gboolean cvImageWidget_expose(GtkWidget* widget, GdkEventExpose* event, g } #endif //GTK_VERSION3 +static std::shared_ptr namedWindow_(const std::string& name, int flags); CV_IMPL int cvNamedWindow( const char* name, int flags ) { cvInitSystem(name ? 1 : 0,(char**)&name); @@ -1060,8 +1110,16 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) { return 1; } + auto window = namedWindow_(name, flags); + return window ? 1 : 0; +} + +static std::shared_ptr namedWindow_(const std::string& name, int flags) +{ + cvInitSystem(0, NULL); - Ptr window = makePtr(name); + auto window_ptr = std::make_shared(name); + CvWindow* window = window_ptr.get(); window->flags = flags; window->status = CV_WINDOW_NORMAL;//YV @@ -1116,9 +1174,12 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) #endif //GTK_VERSION3_4 gtk_widget_show( window->frame ); - gtk_window_set_title( GTK_WINDOW(window->frame), name ); + gtk_window_set_title(GTK_WINDOW(window->frame), name.c_str()); - g_windows.push_back(window); + { + AutoLock lock(getWindowMutex()); + getGTKWindows().push_back(window_ptr); + } bool b_nautosize = ((flags & CV_WINDOW_AUTOSIZE) == 0); gtk_window_set_resizable( GTK_WINDOW(window->frame), b_nautosize ); @@ -1134,10 +1195,10 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) #ifdef HAVE_OPENGL if (window->useGl) - cvSetOpenGlContext(name); + cvSetOpenGlContext(name.c_str()); #endif - return 1; + return window_ptr; } @@ -1152,7 +1213,7 @@ CV_IMPL void cvSetOpenGlContext(const char* name) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if (!window) CV_Error( CV_StsNullPtr, "NULL window" ); @@ -1172,7 +1233,7 @@ CV_IMPL void cvUpdateWindow(const char* name) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if (!window) return; @@ -1186,7 +1247,7 @@ CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback call CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if( !window ) return; @@ -1203,13 +1264,21 @@ CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback call CvWindow::~CvWindow() { + if (frame) + destroy(); +} + +inline void CvWindow::destroy() +{ + CV_LOG_INFO(NULL, "OpenCV/UI: destroying GTK window: " << name); gtk_widget_destroy(frame); + frame = nullptr; } static void checkLastWindow() { // if last window... - if (g_windows.empty()) + if (getGTKWindows().empty()) { #ifdef HAVE_GTHREAD if( thread_started ) @@ -1236,11 +1305,13 @@ static void checkLastWindow() } } -static void icvDeleteWindow( CvWindow* window ) +static +void icvDeleteWindow_( CvWindow* window ) { + AutoLock lock(getWindowMutex()); + auto& g_windows = getGTKWindows(); bool found = false; - for (std::vector< Ptr >::iterator i = g_windows.begin(); - i != g_windows.end(); ++i) + for (auto i = g_windows.begin(); i != g_windows.end(); ++i) { if (i->get() == window) { @@ -1249,8 +1320,7 @@ static void icvDeleteWindow( CvWindow* window ) break; } } - CV_Assert(found && "Can't destroy non-registered window"); - + CV_LOG_IF_WARNING(NULL, !found, "OpenCV/GTK: Can't destroy non-registered window"); checkLastWindow(); } @@ -1259,10 +1329,10 @@ CV_IMPL void cvDestroyWindow( const char* name ) CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); + auto& g_windows = getGTKWindows(); bool found = false; - for (std::vector< Ptr >::iterator i = g_windows.begin(); - i != g_windows.end(); ++i) + for (auto i = g_windows.begin(); i != g_windows.end(); ++i) { if (i->get()->name == name) { @@ -1271,7 +1341,7 @@ CV_IMPL void cvDestroyWindow( const char* name ) break; } } - CV_Assert(found && "Can't destroy non-registered window"); + CV_LOG_IF_ERROR(NULL, !found, "OpenCV/GTK: Can't destroy non-registered window: '" << name << "'"); checkLastWindow(); } @@ -1282,7 +1352,7 @@ cvDestroyAllWindows( void ) { CV_LOCK_MUTEX(); - g_windows.clear(); + getGTKWindows().clear(); checkLastWindow(); } @@ -1305,7 +1375,7 @@ cvShowImage( const char* name, const CvArr* arr ) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if(!window) { cvNamedWindow(name, 1); @@ -1328,16 +1398,24 @@ cvShowImage( const char* name, const CvArr* arr ) } } +static void resizeWindow_(const std::shared_ptr& window, int width, int height); CV_IMPL void cvResizeWindow(const char* name, int width, int height ) { CV_Assert(name && "NULL name string"); CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if(!window) return; + return resizeWindow_(window, width, height); +} + +static +void resizeWindow_(const std::shared_ptr& window, int width, int height) +{ + CV_Assert(window); CvImageWidget* image_widget = CV_IMAGE_WIDGET( window->widget ); //if(image_widget->flags & CV_WINDOW_AUTOSIZE) //EXIT; @@ -1357,26 +1435,30 @@ CV_IMPL void cvMoveWindow( const char* name, int x, int y ) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(name); + const auto window = icvFindWindowByName(name); if(!window) return; gtk_window_move( GTK_WINDOW(window->frame), x, y ); } - -static CvTrackbar* -icvFindTrackbarByName( const CvWindow* window, const char* name ) +static +std::shared_ptr icvFindTrackbarByName(const std::shared_ptr& window, const std::string& name) { - for (size_t i = 0; i < window->trackbars.size(); ++i) + CV_Assert(window); + auto& trackbars = window->trackbars; + for(size_t i = 0; i < trackbars.size(); ++i) { - CvTrackbar* trackbar = window->trackbars[i].get(); + auto trackbar = trackbars[i]; + if (!trackbar) + continue; if (trackbar->name == name) return trackbar; } - return NULL; + return std::shared_ptr(); } + static int icvCreateTrackbar( const char* trackbar_name, const char* window_name, int* val, int count, CvTrackbarCallback on_notify, @@ -1390,16 +1472,16 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if(!window) return 0; - CvTrackbar* trackbar = icvFindTrackbarByName(window, trackbar_name); - if (!trackbar) + auto trackbar_ = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar_) { - Ptr trackbar_ = makePtr(trackbar_name); - trackbar = trackbar_.get(); - trackbar->parent = window; + trackbar_ = std::make_shared(trackbar_name); + CvTrackbar* trackbar = trackbar_.get(); + trackbar->parent = window.get(); window->trackbars.push_back(trackbar_); GtkWidget* hscale_box = gtk_hbox_new( FALSE, 10 ); @@ -1418,6 +1500,8 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, gtk_widget_show( hscale_box ); } + CvTrackbar* trackbar = trackbar_.get(); CV_DbgAssert(trackbar); + if( val ) { int value = *val; @@ -1444,7 +1528,6 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, return 1; } - CV_IMPL int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* val, int count, CvTrackbarCallback on_notify ) @@ -1453,7 +1536,6 @@ cvCreateTrackbar( const char* trackbar_name, const char* window_name, on_notify, 0, 0); } - CV_IMPL int cvCreateTrackbar2( const char* trackbar_name, const char* window_name, int* val, int count, CvTrackbarCallback2 on_notify2, @@ -1463,6 +1545,52 @@ cvCreateTrackbar2( const char* trackbar_name, const char* window_name, 0, on_notify2, userdata); } +static +std::shared_ptr createTrackbar_( + const std::shared_ptr& window, const std::string& name, + int count, + TrackbarCallback onChange, void* userdata +) +{ + CV_Assert(window); + CV_Assert(!name.empty()); + + if (count <= 0) + CV_Error(Error::StsOutOfRange, "Bad trackbar maximal value"); + + auto trackbar_ = std::make_shared(name); + CvTrackbar* trackbar = trackbar_.get(); + trackbar->parent = window.get(); + window->trackbars.push_back(trackbar_); + + GtkWidget* hscale_box = gtk_hbox_new( FALSE, 10 ); + GtkWidget* hscale_label = gtk_label_new(name.c_str()); + GtkWidget* hscale = gtk_hscale_new_with_range( 0, count, 1 ); + gtk_scale_set_digits( GTK_SCALE(hscale), 0 ); + //gtk_scale_set_value_pos( hscale, GTK_POS_TOP ); + gtk_scale_set_draw_value( GTK_SCALE(hscale), TRUE ); + + trackbar->widget = hscale; + gtk_box_pack_start( GTK_BOX(hscale_box), hscale_label, FALSE, FALSE, 5 ); + gtk_widget_show( hscale_label ); + gtk_box_pack_start( GTK_BOX(hscale_box), hscale, TRUE, TRUE, 5 ); + gtk_widget_show( hscale ); + gtk_box_pack_start( GTK_BOX(window->paned), hscale_box, FALSE, FALSE, 5 ); + gtk_widget_show( hscale_box ); + + trackbar->maxval = count; + trackbar->onChangeCallback = onChange; + trackbar->userdata = userdata; + g_signal_connect(trackbar->widget, "value-changed", + G_CALLBACK(icvOnTrackbar), trackbar); + + // queue a widget resize to trigger a window resize to + // compensate for the addition of trackbars + gtk_widget_queue_resize(GTK_WIDGET(window->widget)); + + return trackbar_; +} + CV_IMPL void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) @@ -1471,7 +1599,7 @@ cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* par CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if (!window) return; @@ -1487,18 +1615,18 @@ CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if (!window) return -1; - CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); + const auto trackbar = icvFindTrackbarByName(window,trackbar_name); if (!trackbar) return -1; return trackbar->pos; } - +static void setTrackbarPos_(const std::shared_ptr& trackbar, int pos); CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) { CV_Assert(window_name && "NULL window name"); @@ -1506,24 +1634,27 @@ CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_nam CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if(!window) return; - CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); - if( trackbar ) - { - if( pos < trackbar->minval ) - pos = trackbar->minval; - - if( pos > trackbar->maxval ) - pos = trackbar->maxval; - } - else + const auto trackbar = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar) { CV_Error( CV_StsNullPtr, "No trackbar found" ); } + return setTrackbarPos_(trackbar, pos); +} + +static void setTrackbarPos_(const std::shared_ptr& trackbar, int pos) +{ + CV_Assert(trackbar); + CV_CheckLE(trackbar->minval, trackbar->maxval, ""); + + pos = std::max(pos, trackbar->minval); + pos = std::min(pos, trackbar->maxval); + gtk_range_set_value( GTK_RANGE(trackbar->widget), pos ); } @@ -1535,11 +1666,11 @@ CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if(!window) return; - CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); + const auto trackbar = icvFindTrackbarByName(window,trackbar_name); if(!trackbar) return; @@ -1556,11 +1687,11 @@ CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if(!window) return; - CvTrackbar* trackbar = icvFindTrackbarByName(window,trackbar_name); + const auto trackbar = icvFindTrackbarByName(window,trackbar_name); if(!trackbar) return; @@ -1576,7 +1707,7 @@ CV_IMPL void* cvGetWindowHandle( const char* window_name ) CV_LOCK_MUTEX(); - CvWindow* window = icvFindWindowByName(window_name); + const auto window = icvFindWindowByName(window_name); if(!window) return NULL; @@ -1747,6 +1878,10 @@ static void icvOnTrackbar( GtkWidget* widget, gpointer user_data ) trackbar->widget == widget ) { trackbar->pos = pos; + if (trackbar->onChangeCallback) + trackbar->onChangeCallback(pos, trackbar->userdata); + + // deprecated if( trackbar->data ) *trackbar->data = pos; if( trackbar->notify2 ) @@ -1762,7 +1897,14 @@ static gboolean icvOnClose( GtkWidget* widget, GdkEvent* /*event*/, gpointer use if( window->signature == CV_WINDOW_MAGIC_VAL && window->frame == widget ) { - icvDeleteWindow(window); + try + { + icvDeleteWindow_(window); + } + catch (...) + { + CV_LOG_WARNING(NULL, "OpenCV/GTK: unexpected C++ exception in icvDeleteWindow_"); + } } return TRUE; } @@ -1771,24 +1913,26 @@ static gboolean icvOnClose( GtkWidget* widget, GdkEvent* /*event*/, gpointer use static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_data ) { // TODO move this logic to CvImageWidget + // TODO add try-catch wrappers into all callbacks CvWindow* window = (CvWindow*)user_data; + if (!window || !widget || + window->signature != CV_WINDOW_MAGIC_VAL || + window->widget != widget || + !window->on_mouse) + return FALSE; + CvPoint2D32f pt32f = {-1., -1.}; CvPoint pt = {-1,-1}; int cv_event = -1, state = 0, flags = 0; CvImageWidget * image_widget = CV_IMAGE_WIDGET( widget ); - if( window->signature != CV_WINDOW_MAGIC_VAL || - window->widget != widget || !window->widget || - !window->on_mouse /*|| !image_widget->original_image*/) - return FALSE; - if( event->type == GDK_MOTION_NOTIFY ) { GdkEventMotion* event_motion = (GdkEventMotion*)event; cv_event = CV_EVENT_MOUSEMOVE; - pt32f.x = cvRound(event_motion->x); - pt32f.y = cvRound(event_motion->y); + pt32f.x = cvFloor(event_motion->x); + pt32f.y = cvFloor(event_motion->y); state = event_motion->state; } else if( event->type == GDK_BUTTON_PRESS || @@ -1796,8 +1940,8 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da event->type == GDK_2BUTTON_PRESS ) { GdkEventButton* event_button = (GdkEventButton*)event; - pt32f.x = cvRound(event_button->x); - pt32f.y = cvRound(event_button->y); + pt32f.x = cvFloor(event_button->x); + pt32f.y = cvFloor(event_button->y); if( event_button->type == GDK_BUTTON_PRESS ) @@ -1874,9 +2018,12 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da pt = cvPointFrom32f( pt32f ); } -// if((unsigned)pt.x < (unsigned)(image_widget->original_image->width) && -// (unsigned)pt.y < (unsigned)(image_widget->original_image->height) ) + if (!image_widget->original_image/*OpenGL*/ || ( + (unsigned)pt.x < (unsigned)(image_widget->original_image->width) && + (unsigned)pt.y < (unsigned)(image_widget->original_image->height) + )) { + state &= gtk_accelerator_get_default_mod_mask(); flags |= BIT_MAP(state, GDK_SHIFT_MASK, CV_EVENT_FLAG_SHIFTKEY) | BIT_MAP(state, GDK_CONTROL_MASK, CV_EVENT_FLAG_CTRLKEY) | BIT_MAP(state, GDK_MOD1_MASK, CV_EVENT_FLAG_ALTKEY) | @@ -1916,7 +2063,7 @@ CV_IMPL int cvWaitKey( int delay ) expired = !g_cond_timed_wait(cond_have_key, last_key_mutex, &timer); } else{ - if (g_windows.empty()) + if (getGTKWindows().empty()) { CV_LOG_WARNING(NULL, "cv::waitKey() is called without timeout and missing active windows. Ignoring"); } @@ -1928,7 +2075,8 @@ CV_IMPL int cvWaitKey( int delay ) } my_last_key = last_key; g_mutex_unlock(last_key_mutex); - if(expired || g_windows.empty()){ + if (expired || getGTKWindows().empty()) + { return -1; } return my_last_key; @@ -1941,7 +2089,7 @@ CV_IMPL int cvWaitKey( int delay ) if( delay > 0 ) timer = g_timeout_add( delay, icvAlarm, &expired ); last_key = -1; - while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && (delay > 0 || !g_windows.empty())) + while( gtk_main_iteration_do(TRUE) && last_key < 0 && !expired && (delay > 0 || !getGTKWindows().empty())) ; if( delay > 0 && !expired ) @@ -1950,8 +2098,340 @@ CV_IMPL int cvWaitKey( int delay ) return last_key; } +namespace cv { namespace impl { -#endif // HAVE_GTK -#endif // _WIN32 +using namespace cv::highgui_backend; + +class GTKTrackbar; + +class GTKWindow + : public UIWindow + , public std::enable_shared_from_this +{ +protected: + const std::string name_; + std::weak_ptr window_; + std::map > trackbars_; +public: + GTKWindow(const std::string& name, const std::shared_ptr& window) + : name_(name) + , window_(window) + { + // nothing + } + + ~GTKWindow() CV_OVERRIDE + { + if (!window_.expired()) + destroy(); + CV_LOG_DEBUG(NULL, "OpenCV/UI/GTK: GTKWindow(" << name_ << ") is disposed"); + } + + const std::string& getID() const CV_OVERRIDE { return name_; } + + bool isActive() const CV_OVERRIDE { return !window_.expired(); } + + void destroy() CV_OVERRIDE + { + cv::AutoLock lock(getWindowMutex()); + if (!window_.expired()) + { + auto window = window_.lock(); + if (window) + window->destroy(); + window_.reset(); + } + } + + void imshow(InputArray image) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + CvImageWidget* image_widget = CV_IMAGE_WIDGET(window->widget); + CV_Assert(image_widget); + Mat img = image.getMat(); + CvMat c_img = cvMat(img); // TODO Drop C-API + cvImageWidgetSetImage(image_widget, &c_img); + } + + double getProperty(int prop) const CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + // see cvGetWindowProperty + switch (prop) + { + case CV_WND_PROP_FULLSCREEN: + return (double)window->status; + + case CV_WND_PROP_AUTOSIZE: + return (window->flags & CV_WINDOW_AUTOSIZE) ? 1.0 : 0.0; + + case CV_WND_PROP_ASPECTRATIO: + return getRatioWindow_(window); -/* End of file. */ +#ifdef HAVE_OPENGL + case CV_WND_PROP_OPENGL: + return window->useGl ? 1.0 : 0.0; +#endif + + default: + break; + } + return std::numeric_limits::quiet_NaN(); + } + + bool setProperty(int prop, double value) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + // see cvSetWindowProperty + switch (prop) + { + case CV_WND_PROP_FULLSCREEN: + if (value != CV_WINDOW_NORMAL && value != CV_WINDOW_FULLSCREEN) // bad arg + break; + setModeWindow_(window, value); + return true; + + default: + break; + } + return false; + } + + void resize(int width, int height) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + resizeWindow_(window, width, height); + } + + void move(int x, int y) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + gtk_window_move(GTK_WINDOW(window->frame), x, y); + } + + Rect getImageRect() const CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + return getImageRect_(window); + } + + void setTitle(const std::string& title) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + gtk_window_set_title(GTK_WINDOW(window->frame), title.c_str()); + } + + void setMouseCallback(MouseCallback onMouse, void* userdata /*= 0*/) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + window->on_mouse = onMouse; + window->on_mouse_param = userdata; + } + + std::shared_ptr createTrackbar( + const std::string& name, + int count, + TrackbarCallback onChange /*= 0*/, + void* userdata /*= 0*/ + ) CV_OVERRIDE + { + auto window = window_.lock(); + CV_Assert(window); + CV_LOG_INFO(NULL, "OpenCV/UI: Creating GTK trackbar at '" << name_ << "': '" << name << "'"); + auto trackbar = createTrackbar_(window, name, count, onChange, userdata); + auto ui_trackbar = std::make_shared(name, trackbar, shared_from_this()); + { + cv::AutoLock lock(getWindowMutex()); + trackbars_.emplace(name, ui_trackbar); + } + return std::static_pointer_cast(ui_trackbar); + } + + std::shared_ptr findTrackbar(const std::string& name) CV_OVERRIDE + { + cv::AutoLock lock(getWindowMutex()); + auto i = trackbars_.find(name); + if (i != trackbars_.end()) + { + return std::static_pointer_cast(i->second); + } + return std::shared_ptr(); + } +}; // GTKWindow + + +class GTKTrackbar : public UITrackbar +{ +protected: + /*const*/ std::string name_; + std::weak_ptr trackbar_; + std::weak_ptr parent_; + std::map > trackbars_; +public: + GTKTrackbar(const std::string& name, const std::shared_ptr& trackbar, const std::shared_ptr& parent) + : trackbar_(trackbar) + , parent_(parent) + { + name_ = std::string("<") + name + ">@" + parent->getID(); + } + + ~GTKTrackbar() CV_OVERRIDE + { + if (!trackbar_.expired()) + destroy(); + CV_LOG_DEBUG(NULL, "OpenCV/UI/GTK: GTKTrackbar(" << name_ << ") is disposed"); + } + + const std::string& getID() const CV_OVERRIDE { return name_; } + + bool isActive() const CV_OVERRIDE { return !trackbar_.expired(); } + + void destroy() CV_OVERRIDE + { + // nothing (destroyed with parent window, dedicated trackbar removal is not supported) + } + + int getPos() const CV_OVERRIDE + { + auto trackbar = trackbar_.lock(); + CV_Assert(trackbar); + return trackbar->pos; + } + void setPos(int pos) CV_OVERRIDE + { + auto trackbar = trackbar_.lock(); + CV_Assert(trackbar); + return setTrackbarPos_(trackbar, pos); + } + + cv::Range getRange() const CV_OVERRIDE + { + auto trackbar = trackbar_.lock(); + CV_Assert(trackbar); + return cv::Range(trackbar->minval, trackbar->maxval); + } + + void setRange(const cv::Range& range) CV_OVERRIDE + { + auto trackbar = trackbar_.lock(); + CV_Assert(trackbar); + CV_CheckLE(range.start, range.end, "Invalid trackbar range"); + gtk_range_set_range(GTK_RANGE(trackbar->widget), range.start, range.end); + } +}; // GTKTrackbar + + +class GTKBackendUI : public UIBackend +{ +public: + GTKBackendUI() + { + // NB: avoid static initialization order fiasco + (void)getGTKWindows(); + } + ~GTKBackendUI() CV_OVERRIDE + { + destroyAllWindows(); + } + + void destroyAllWindows() CV_OVERRIDE + { + cvDestroyAllWindows(); + } + + // namedWindow + virtual std::shared_ptr createWindow( + const std::string& winname, + int flags + ) CV_OVERRIDE + { + CV_LOG_INFO(NULL, "OpenCV/UI: Creating GTK window: " << winname << " (" << flags << ")"); + auto window = namedWindow_(winname, flags); + auto ui_window = std::make_shared(winname, window); + return ui_window; + } + + int waitKeyEx(int delay) CV_OVERRIDE + { + return cvWaitKey(delay); + } + int pollKey() CV_OVERRIDE + { + return cvWaitKey(1); // TODO + } +}; // GTKBackendUI + +static +std::shared_ptr& getInstance() +{ + static std::shared_ptr g_instance = std::make_shared(); + return g_instance; +} + +} // namespace impl + +#ifndef BUILD_PLUGIN +namespace highgui_backend { + +std::shared_ptr createUIBackendGTK() +{ + return impl::getInstance(); +} + +} // namespace highgui_backend +#endif + +} // namespace + +#ifdef BUILD_PLUGIN + +#define ABI_VERSION 0 +#define API_VERSION 0 +#include "plugin_api.hpp" + +static +CvResult cv_getInstance(CV_OUT CvPluginUIBackend* handle) CV_NOEXCEPT +{ + try + { + if (!handle) + return CV_ERROR_FAIL; + *handle = cv::impl::getInstance().get(); + return CV_ERROR_OK; + } + catch (...) + { + return CV_ERROR_FAIL; + } +} + +static const OpenCV_UI_Plugin_API plugin_api = +{ + { + sizeof(OpenCV_UI_Plugin_API), ABI_VERSION, API_VERSION, + CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS, + "GTK" CVAUX_STR(GTK_MAJOR_VERSION) " OpenCV UI plugin" + }, + { + /* 1*/cv_getInstance + } +}; + +const OpenCV_UI_Plugin_API* CV_API_CALL opencv_ui_plugin_init_v0(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT +{ + if (requested_abi_version == ABI_VERSION && requested_api_version <= API_VERSION) + return &plugin_api; + return NULL; +} + +#endif // BUILD_PLUGIN + +#endif // HAVE_GTK diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index c4f2ddd2a603..716af1094c29 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -41,12 +41,17 @@ #include "precomp.hpp" +#ifdef HAVE_WIN32UI + +#include +#include + +#include "backend.hpp" + using namespace cv; #include // required for GET_X_LPARAM() and GET_Y_LPARAM() macros -#if defined _WIN32 - #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" #endif @@ -60,14 +65,12 @@ using namespace cv; #include #include #include -#include #ifdef HAVE_OPENGL #include #include #include #include -#include "opencv2/highgui.hpp" #include #include "opencv2/core/opengl.hpp" #endif @@ -78,7 +81,7 @@ static const char* trackbar_text = #if defined _M_X64 || defined __x86_64 || defined _M_ARM64 #define icvGetWindowLongPtr GetWindowLongPtr -#define icvSetWindowLongPtr( hwnd, id, ptr ) SetWindowLongPtr( hwnd, id, (LONG_PTR)(ptr) ) +#define icvSetWindowLongPtr(hwnd, id, ptr) SetWindowLongPtr(hwnd, id, (LONG_PTR)(ptr)) #define icvGetClassLongPtr GetClassLongPtr #define CV_USERDATA GWLP_USERDATA @@ -89,7 +92,7 @@ static const char* trackbar_text = #else #define icvGetWindowLongPtr GetWindowLong -#define icvSetWindowLongPtr( hwnd, id, ptr ) SetWindowLong( hwnd, id, (size_t)ptr ) +#define icvSetWindowLongPtr(hwnd, id, ptr) SetWindowLong(hwnd, id, (size_t)ptr) #define icvGetClassLongPtr GetClassLong #define CV_USERDATA GWL_USERDATA @@ -116,13 +119,13 @@ static inline void mingw_strcat_s(char *dest, size_t destsz, const char *src){ #define strcat_s mingw_strcat_s #endif -static void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin ) +static void FillBitmapInfo(BITMAPINFO* bmi, int width, int height, int bpp, int origin) { - assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32)); + CV_Assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32)); BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); - memset( bmih, 0, sizeof(*bmih)); + memset(bmih, 0, sizeof(*bmih)); bmih->biSize = sizeof(BITMAPINFOHEADER); bmih->biWidth = width; bmih->biHeight = origin ? abs(height) : -abs(height); @@ -130,11 +133,11 @@ static void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int bmih->biBitCount = (unsigned short)bpp; bmih->biCompression = BI_RGB; - if( bpp == 8 ) + if (bpp == 8) { RGBQUAD* palette = bmi->bmiColors; int i; - for( i = 0; i < 256; i++ ) + for (i = 0; i < 256; i++) { palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; palette[i].rgbReserved = 0; @@ -144,68 +147,91 @@ static void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int struct CvWindow; -typedef struct CvTrackbar +struct CvTrackbar : public std::enable_shared_from_this { + CvTrackbar(CvWindow& window, const std::string& name_) + : signature(CV_TRACKBAR_MAGIC_VAL) + , name(name_) + , parent(&window) + { + // nothing + } + ~CvTrackbar() + { + signature = -1; + } + int signature; - HWND hwnd; - char* name; - CvTrackbar* next; - CvWindow* parent; - HWND buddy; - int* data; - int pos; - int maxval; - int minval; - void (*notify)(int); - void (*notify2)(int, void*); - void* userdata; - int id; -} -CvTrackbar; + HWND hwnd = 0; + std::string name; + CvWindow* parent; // TODO weak_ptr + HWND buddy = 0; + int* data = nullptr; + int pos = 0; + int maxval = 0; + int minval = 0; + void (*notify)(int) = nullptr; // deprecated + void (*notify2)(int, void*) = nullptr; // deprecated + TrackbarCallback onChangeCallback = nullptr; + void* userdata = nullptr; + int id = -1; +}; -typedef struct CvWindow +struct CvWindow : public std::enable_shared_from_this { + CvWindow(const std::string& name_) + : signature(CV_WINDOW_MAGIC_VAL) + , name(name_) + { + // nothing + } + + ~CvWindow() + { + signature = -1; + } + + void destroy(); + int signature; - HWND hwnd; - char* name; - CvWindow* prev; - CvWindow* next; - HWND frame; + cv::Mutex mutex; + HWND hwnd = 0; + std::string name; + HWND frame = 0; - HDC dc; - HGDIOBJ image; - int last_key; - int flags; - int status;//0 normal, 1 fullscreen (YV) + HDC dc = 0; + HGDIOBJ image = 0; + int last_key = 0; + int flags = 0; + int status = 0;//0 normal, 1 fullscreen (YV) - CvMouseCallback on_mouse; - void* on_mouse_param; + CvMouseCallback on_mouse = nullptr; + void* on_mouse_param = nullptr; struct { - HWND toolbar; - int pos; - int rows; - WNDPROC toolBarProc; - CvTrackbar* first; + HWND toolbar = 0; + int pos = 0; + int rows = 0; + WNDPROC toolBarProc = nullptr; + std::vector< std::shared_ptr > trackbars; } toolbar; - int width; - int height; + int width = -1; + int height = -1; // OpenGL support #ifdef HAVE_OPENGL - bool useGl; - HGLRC hGLRC; + bool useGl = false; + HGLRC hGLRC = 0; - CvOpenGlDrawCallback glDrawCallback; - void* glDrawData; + CvOpenGlDrawCallback glDrawCallback = nullptr; + void* glDrawData = nullptr; #endif -} -CvWindow; +}; #define HG_BUDDY_WIDTH 130 @@ -221,19 +247,50 @@ CvWindow; #define TBM_GETTOOLTIPS (WM_USER + 30) #endif -static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static LRESULT CALLBACK MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static void icvUpdateWindowPos( CvWindow* window ); +static +std::vector< std::shared_ptr >& getWindowsList() +{ + static std::vector< std::shared_ptr > g_windows; + return g_windows; +} + -static CvWindow* hg_windows = 0; +// Mutex must be locked +static +std::shared_ptr icvFindWindowByName(const std::string& name) +{ + auto& g_windows = getWindowsList(); + for (auto it = g_windows.begin(); it != g_windows.end(); ++it) + { + auto window = *it; + if (!window) + continue; + if (window->name == name) + return window; + } + return std::shared_ptr(); +} + +static inline +std::shared_ptr icvFindWindowByName(const char* name) +{ + CV_Assert(name); + return icvFindWindowByName(std::string(name)); +} + + + +static LRESULT CALLBACK HighGUIProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static void icvUpdateWindowPos(CvWindow& window); typedef int (CV_CDECL * CvWin32WindowCallback)(HWND, UINT, WPARAM, LPARAM, int*); static CvWin32WindowCallback hg_on_preprocess = 0, hg_on_postprocess = 0; static HINSTANCE hg_hinstance = 0; -static const char* highGUIclassName = "HighGUI class"; -static const char* mainHighGUIclassName = "Main HighGUI class"; +static const char* const highGUIclassName = "HighGUI class"; +static const char* const mainHighGUIclassName = "Main HighGUI class"; static void icvCleanupHighgui() { @@ -242,15 +299,15 @@ static void icvCleanupHighgui() UnregisterClass(mainHighGUIclassName, hg_hinstance); } -CV_IMPL int cvInitSystem( int, char** ) +CV_IMPL int cvInitSystem(int, char**) { static int wasInitialized = 0; // check initialization status - if( !wasInitialized ) + if (!wasInitialized) { - // Initialize the storage - hg_windows = 0; + (void)getWindowMutex(); // force mutex initialization + (void)getWindowsList(); // Initialize the storage // Register the class WNDCLASS wndc; @@ -262,7 +319,7 @@ CV_IMPL int cvInitSystem( int, char** ) wndc.lpszClassName = highGUIclassName; wndc.lpszMenuName = highGUIclassName; wndc.hIcon = LoadIcon(0, IDI_APPLICATION); - wndc.hCursor = (HCURSOR)LoadCursor(0, (LPSTR)(size_t)IDC_CROSS ); + wndc.hCursor = (HCURSOR)LoadCursor(0, (LPSTR)(size_t)IDC_CROSS); wndc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); RegisterClass(&wndc); @@ -273,12 +330,12 @@ CV_IMPL int cvInitSystem( int, char** ) wndc.lpfnWndProc = MainWindowProc; RegisterClass(&wndc); - atexit( icvCleanupHighgui ); + atexit(icvCleanupHighgui); wasInitialized = 1; } - setlocale(LC_NUMERIC,"C"); + setlocale(LC_NUMERIC,"C"); // FIXIT must be removed return 0; } @@ -287,50 +344,58 @@ CV_IMPL int cvStartWindowThread(){ return 0; } -static CvWindow* icvFindWindowByName( const char* name ) -{ - CvWindow* window = hg_windows; - - for( ; window != 0 && strcmp( name, window->name) != 0; window = window->next ) - ; - - return window; -} - -static CvWindow* icvWindowByHWND( HWND hwnd ) +static std::shared_ptr icvWindowByHWND(HWND hwnd) { - CvWindow* window = (CvWindow*)icvGetWindowLongPtr( hwnd, CV_USERDATA ); - return window != 0 && hg_windows != 0 && + AutoLock lock(getWindowMutex()); + CvWindow* window = (CvWindow*)icvGetWindowLongPtr(hwnd, CV_USERDATA); + window = window != 0 && window->signature == CV_WINDOW_MAGIC_VAL ? window : 0; + if (window) + { + return window->shared_from_this(); + } + else + { + return std::shared_ptr(); + } } -static CvTrackbar* icvTrackbarByHWND( HWND hwnd ) +static std::shared_ptr icvTrackbarByHWND(HWND hwnd) { - CvTrackbar* trackbar = (CvTrackbar*)icvGetWindowLongPtr( hwnd, CV_USERDATA ); - return trackbar != 0 && trackbar->signature == CV_TRACKBAR_MAGIC_VAL && + AutoLock lock(getWindowMutex()); + CvTrackbar* trackbar = (CvTrackbar*)icvGetWindowLongPtr(hwnd, CV_USERDATA); + trackbar = trackbar != 0 && trackbar->signature == CV_TRACKBAR_MAGIC_VAL && trackbar->hwnd == hwnd ? trackbar : 0; + if (trackbar) + { + return trackbar->shared_from_this(); + } + else + { + return std::shared_ptr(); + } } -static const char* icvWindowPosRootKey = "Software\\OpenCV\\HighGUI\\Windows\\"; +static const char* const icvWindowPosRootKey = "Software\\OpenCV\\HighGUI\\Windows\\"; // Window positions saving/loading added by Philip Gruebele. //pgruebele@cox.net // Restores the window position from the registry saved position. static void -icvLoadWindowPos( const char* name, CvRect& rect ) +icvLoadWindowPos(const char* name, CvRect& rect) { HKEY hkey; char szKey[1024]; - strcpy_s( szKey, 1024, icvWindowPosRootKey ); - strcat_s( szKey, 1024, name ); + strcpy_s(szKey, 1024, icvWindowPosRootKey); + strcat_s(szKey, 1024, name); rect.x = rect.y = CW_USEDEFAULT; rect.width = rect.height = 320; - if( RegOpenKeyEx(HKEY_CURRENT_USER,szKey,0,KEY_QUERY_VALUE,&hkey) == ERROR_SUCCESS ) + if (RegOpenKeyEx(HKEY_CURRENT_USER,szKey,0,KEY_QUERY_VALUE,&hkey) == ERROR_SUCCESS) { // Yes we are installed. DWORD dwType = 0; @@ -379,16 +444,16 @@ icvLoadWindowPos( const char* name, CvRect& rect ) //pgruebele@cox.net // philipg. Saves the window position in the registry static void -icvSaveWindowPos( const char* name, CvRect rect ) +icvSaveWindowPos(const char* name, CvRect rect) { static const DWORD MAX_RECORD_COUNT = 100; HKEY hkey; char szKey[1024]; char rootKey[1024]; - strcpy_s( szKey, 1024, icvWindowPosRootKey ); - strcat_s( szKey, 1024, name ); + strcpy_s(szKey, 1024, icvWindowPosRootKey); + strcat_s(szKey, 1024, name); - if( RegOpenKeyEx( HKEY_CURRENT_USER,szKey,0,KEY_READ,&hkey) != ERROR_SUCCESS ) + if (RegOpenKeyEx(HKEY_CURRENT_USER,szKey,0,KEY_READ,&hkey) != ERROR_SUCCESS) { HKEY hroot; DWORD count = 0; @@ -396,40 +461,40 @@ icvSaveWindowPos( const char* name, CvRect rect ) char oldestKey[1024]; char currentKey[1024]; - strcpy_s( rootKey, 1024, icvWindowPosRootKey ); + strcpy_s(rootKey, 1024, icvWindowPosRootKey); rootKey[strlen(rootKey)-1] = '\0'; - if( RegCreateKeyEx(HKEY_CURRENT_USER, rootKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ+KEY_WRITE, 0, &hroot, NULL) != ERROR_SUCCESS ) - //RegOpenKeyEx( HKEY_CURRENT_USER,rootKey,0,KEY_READ,&hroot) != ERROR_SUCCESS ) + if (RegCreateKeyEx(HKEY_CURRENT_USER, rootKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ+KEY_WRITE, 0, &hroot, NULL) != ERROR_SUCCESS) + //RegOpenKeyEx(HKEY_CURRENT_USER,rootKey,0,KEY_READ,&hroot) != ERROR_SUCCESS) return; for(;;) { DWORD csize = sizeof(currentKey); FILETIME accesstime = { 0, 0 }; - LONG code = RegEnumKeyEx( hroot, count, currentKey, &csize, NULL, NULL, NULL, &accesstime ); - if( code != ERROR_SUCCESS && code != ERROR_MORE_DATA ) + LONG code = RegEnumKeyEx(hroot, count, currentKey, &csize, NULL, NULL, NULL, &accesstime); + if (code != ERROR_SUCCESS && code != ERROR_MORE_DATA) break; count++; - if( oldestTime.dwHighDateTime > accesstime.dwHighDateTime || + if (oldestTime.dwHighDateTime > accesstime.dwHighDateTime || (oldestTime.dwHighDateTime == accesstime.dwHighDateTime && - oldestTime.dwLowDateTime > accesstime.dwLowDateTime) ) + oldestTime.dwLowDateTime > accesstime.dwLowDateTime)) { oldestTime = accesstime; - strcpy_s( oldestKey, 1024, currentKey ); + strcpy_s(oldestKey, 1024, currentKey); } } - if( count >= MAX_RECORD_COUNT ) - RegDeleteKey( hroot, oldestKey ); - RegCloseKey( hroot ); + if (count >= MAX_RECORD_COUNT) + RegDeleteKey(hroot, oldestKey); + RegCloseKey(hroot); - if( RegCreateKeyEx(HKEY_CURRENT_USER,szKey,0,NULL,REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hkey, NULL) != ERROR_SUCCESS ) + if (RegCreateKeyEx(HKEY_CURRENT_USER,szKey,0,NULL,REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hkey, NULL) != ERROR_SUCCESS) return; } else { - RegCloseKey( hkey ); - if( RegOpenKeyEx( HKEY_CURRENT_USER,szKey,0,KEY_WRITE,&hkey) != ERROR_SUCCESS ) + RegCloseKey(hkey); + if (RegOpenKeyEx(HKEY_CURRENT_USER,szKey,0,KEY_WRITE,&hkey) != ERROR_SUCCESS) return; } @@ -440,96 +505,101 @@ icvSaveWindowPos( const char* name, CvRect rect ) RegCloseKey(hkey); } +static Rect getImageRect_(CvWindow& window); + CvRect cvGetWindowRect_W32(const char* name) { - RECT rect = { 0 }; - CvRect result = cvRect(-1, -1, -1, -1); - - CV_FUNCNAME( "cvGetWindowRect_W32" ); + CV_FUNCNAME("cvGetWindowRect_W32"); - __BEGIN__; - - CvWindow* window; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - window = icvFindWindowByName( name ); + CV_Error(Error::StsNullPtr, "NULL name string"); + + auto window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - GetClientRect(window->hwnd, &rect); - { + Rect r = getImageRect_(*window); + + CvRect result = cvRect(r.x, r.y, r.width, r.height); + return result; +} + +static Rect getImageRect_(CvWindow& window) +{ + RECT rect = { 0 }; + GetClientRect(window.hwnd, &rect); POINT pt = {rect.left, rect.top}; - ClientToScreen(window->hwnd, &pt); - result = cvRect(pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top); - } - __END__; + ClientToScreen(window.hwnd, &pt); + Rect result(pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top); return result; } double cvGetModeWindow_W32(const char* name)//YV { - double result = -1; + CV_FUNCNAME("cvGetModeWindow_W32"); - CV_FUNCNAME( "cvGetModeWindow_W32" ); - - __BEGIN__; - - CvWindow* window; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); + auto window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - result = window->status; - - __END__; - return result; + return window->status; } -void cvSetModeWindow_W32( const char* name, double prop_value)//Yannick Verdie +static bool setModeWindow_(CvWindow& window, int mode); + +void cvSetModeWindow_W32(const char* name, double prop_value)//Yannick Verdie { - CV_FUNCNAME( "cvSetModeWindow_W32" ); + CV_FUNCNAME("cvSetModeWindow_W32"); + + AutoLock lock(getWindowMutex()); - __BEGIN__; + if (!name) + CV_Error(Error::StsNullPtr, "NULL name string"); - CvWindow* window; + auto window = icvFindWindowByName(name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + (void)setModeWindow_(*window, (int)prop_value); +} - window = icvFindWindowByName( name ); - if( !window ) - CV_ERROR( CV_StsNullPtr, "NULL window" ); +static bool setModeWindow_(CvWindow& window, int mode) +{ + if (window.flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set + return false; - if(window->flags & CV_WINDOW_AUTOSIZE)//if the flag CV_WINDOW_AUTOSIZE is set - EXIT; + if (window.status == mode) + return true; { - DWORD dwStyle = (DWORD)GetWindowLongPtr(window->frame, GWL_STYLE); + DWORD dwStyle = (DWORD)GetWindowLongPtr(window.frame, GWL_STYLE); CvRect position; - if (window->status==CV_WINDOW_FULLSCREEN && prop_value==CV_WINDOW_NORMAL) + if (window.status == CV_WINDOW_FULLSCREEN && mode == CV_WINDOW_NORMAL) { - icvLoadWindowPos(window->name,position ); - SetWindowLongPtr(window->frame, GWL_STYLE, dwStyle | WS_CAPTION | WS_THICKFRAME); + icvLoadWindowPos(window.name.c_str(), position); + SetWindowLongPtr(window.frame, GWL_STYLE, dwStyle | WS_CAPTION | WS_THICKFRAME); - SetWindowPos(window->frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); - window->status=CV_WINDOW_NORMAL; + SetWindowPos(window.frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); + window.status=CV_WINDOW_NORMAL; - EXIT; + return true; } - if (window->status==CV_WINDOW_NORMAL && prop_value==CV_WINDOW_FULLSCREEN) + if (window.status == CV_WINDOW_NORMAL && mode == CV_WINDOW_FULLSCREEN) { //save dimension RECT rect = { 0 }; - GetWindowRect(window->frame, &rect); - CvRect RectCV = cvRect(rect.left, rect.top,rect.right - rect.left, rect.bottom - rect.top); - icvSaveWindowPos(window->name,RectCV ); + GetWindowRect(window.frame, &rect); + CvRect rectCV = cvRect(rect.left, rect.top,rect.right - rect.left, rect.bottom - rect.top); + icvSaveWindowPos(window.name.c_str(), rectCV); //Look at coordinate for fullscreen HMONITOR hMonitor; @@ -542,60 +612,75 @@ void cvSetModeWindow_W32( const char* name, double prop_value)//Yannick Verdie //fullscreen position.x=mi.rcMonitor.left;position.y=mi.rcMonitor.top; position.width=mi.rcMonitor.right - mi.rcMonitor.left;position.height=mi.rcMonitor.bottom - mi.rcMonitor.top; - SetWindowLongPtr(window->frame, GWL_STYLE, dwStyle & ~WS_CAPTION & ~WS_THICKFRAME); + SetWindowLongPtr(window.frame, GWL_STYLE, dwStyle & ~WS_CAPTION & ~WS_THICKFRAME); - SetWindowPos(window->frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); - window->status=CV_WINDOW_FULLSCREEN; + SetWindowPos(window.frame, HWND_TOP, position.x, position.y , position.width,position.height, SWP_NOZORDER | SWP_FRAMECHANGED); + window.status=CV_WINDOW_FULLSCREEN; - EXIT; + return true; } } - __END__; + return false; } +static double getPropTopmost_(CvWindow& window); + double cvGetPropTopmost_W32(const char* name) { - double result = -1; - CV_Assert(name); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if (!window) CV_Error(Error::StsNullPtr, "NULL window"); - LONG style = GetWindowLongA(window->frame, GWL_EXSTYLE); // -20 + return getPropTopmost_(*window); +} + +static double getPropTopmost_(CvWindow& window) +{ + LONG style = GetWindowLongA(window.frame, GWL_EXSTYLE); // -20 if (!style) { std::ostringstream errorMsg; - errorMsg << "window(" << name << "): failed to retrieve extended window style using GetWindowLongA(); error code: " << GetLastError(); - CV_Error(Error::StsError, errorMsg.str().c_str()); + errorMsg << "window(" << window.name << "): failed to retrieve extended window style using GetWindowLongA(); error code: " << GetLastError(); + CV_Error(Error::StsError, errorMsg.str()); } - result = (style & WS_EX_TOPMOST) == WS_EX_TOPMOST; - - return result; + bool result = (style & WS_EX_TOPMOST) == WS_EX_TOPMOST; + return result ? 1.0 : 0.0; } +static bool setPropTopmost_(CvWindow& window, bool topmost); + void cvSetPropTopmost_W32(const char* name, const bool topmost) { CV_Assert(name); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if (!window) CV_Error(Error::StsNullPtr, "NULL window"); + (void)setPropTopmost_(*window, topmost); +} + +static bool setPropTopmost_(CvWindow& window, bool topmost) +{ HWND flag = topmost ? HWND_TOPMOST : HWND_TOP; - BOOL success = SetWindowPos(window->frame, flag, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + BOOL success = SetWindowPos(window.frame, flag, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); if (!success) { std::ostringstream errorMsg; - errorMsg << "window(" << name << "): error reported by SetWindowPos(" << (topmost ? "HWND_TOPMOST" : "HWND_TOP") << "), error code: " << GetLastError(); - CV_Error(Error::StsError, errorMsg.str().c_str()); + errorMsg << "window(" << window.name << "): error reported by SetWindowPos(" << (topmost ? "HWND_TOPMOST" : "HWND_TOP") << "), error code: " << GetLastError(); + CV_Error(Error::StsError, errorMsg.str()); + return false; } + return true; } +static double getPropVsync_(CvWindow& window); + double cvGetPropVsync_W32(const char* name) { #ifndef HAVE_OPENGL @@ -605,40 +690,53 @@ double cvGetPropVsync_W32(const char* name) if (!name) CV_Error(Error::StsNullPtr, "'name' argument must not be NULL"); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if (!window) CV_Error_(Error::StsBadArg, ("there is no window named '%s'", name)); + double result = getPropVsync_(*window); + return cvIsNaN(result) ? -1.0 : result; +#endif +} + +static double getPropVsync_(CvWindow& window) +{ +#ifndef HAVE_OPENGL + CV_UNUSED(window); + CV_Error(Error::OpenGlNotSupported, "Library was built without OpenGL support"); +#else // https://www.khronos.org/opengl/wiki/Swap_Interval // https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_extensions_string.txt // https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_swap_control.txt - if (!wglMakeCurrent(window->dc, window->hGLRC)) + if (!wglMakeCurrent(window.dc, window.hGLRC)) CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context"); typedef const char* (APIENTRY* PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void); PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsString = NULL; wglGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT"); if (wglGetExtensionsString == NULL) - return -1; // wglGetProcAddress failed to get wglGetExtensionsStringEXT + return std::numeric_limits::quiet_NaN(); // wglGetProcAddress failed to get wglGetExtensionsStringEXT const char* wgl_extensions = wglGetExtensionsString(); if (wgl_extensions == NULL) - return -1; // Can't get WGL extensions string + return std::numeric_limits::quiet_NaN(); // Can't get WGL extensions string if (strstr(wgl_extensions, "WGL_EXT_swap_control") == NULL) - return -1; // WGL extensions don't contain WGL_EXT_swap_control + return std::numeric_limits::quiet_NaN(); // WGL extensions don't contain WGL_EXT_swap_control typedef int (APIENTRY* PFNWGLGETSWAPINTERVALPROC)(void); PFNWGLGETSWAPINTERVALPROC wglGetSwapInterval = 0; wglGetSwapInterval = (PFNWGLGETSWAPINTERVALPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); if (wglGetSwapInterval == NULL) - return -1; // wglGetProcAddress failed to get wglGetSwapIntervalEXT + return std::numeric_limits::quiet_NaN(); // wglGetProcAddress failed to get wglGetSwapIntervalEXT return wglGetSwapInterval(); #endif } +static bool setPropVsync_(CvWindow& window, bool enable_vsync); + void cvSetPropVsync_W32(const char* name, const bool enable_vsync) { #ifndef HAVE_OPENGL @@ -649,11 +747,22 @@ void cvSetPropVsync_W32(const char* name, const bool enable_vsync) if (!name) CV_Error(Error::StsNullPtr, "'name' argument must not be NULL"); - CvWindow* window = icvFindWindowByName(name); + auto window = icvFindWindowByName(name); if (!window) CV_Error_(Error::StsBadArg, ("there is no window named '%s'", name)); - if (!wglMakeCurrent(window->dc, window->hGLRC)) + (void)setPropVsync_(*window, enable_vsync); +#endif +} + +static bool setPropVsync_(CvWindow& window, bool enable_vsync) +{ +#ifndef HAVE_OPENGL + CV_UNUSED(window); + CV_UNUSED(enable_vsync); + CV_Error(Error::OpenGlNotSupported, "Library was built without OpenGL support"); +#else + if (!wglMakeCurrent(window.dc, window.hGLRC)) CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context"); typedef const char* (APIENTRY* PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void); @@ -676,47 +785,44 @@ void cvSetPropVsync_W32(const char* name, const bool enable_vsync) CV_Error(Error::OpenGlApiCallError, "wglGetProcAddress failed to get wglSwapIntervalEXT"); wglSwapInterval(enable_vsync); + return true; #endif } -void cv::setWindowTitle(const String& winname, const String& title) +void setWindowTitle_W32(const std::string& name, const std::string& title) { - CvWindow* window = icvFindWindowByName(winname.c_str()); + auto window = icvFindWindowByName(name); if (!window) { - namedWindow(winname); - window = icvFindWindowByName(winname.c_str()); + namedWindow(name); + window = icvFindWindowByName(name); } if (!window) CV_Error(Error::StsNullPtr, "NULL window"); if (!SetWindowText(window->frame, title.c_str())) - CV_Error_(Error::StsError, ("Failed to set \"%s\" window title to \"%s\"", winname.c_str(), title.c_str())); + CV_Error_(Error::StsError, ("Failed to set \"%s\" window title to \"%s\"", name.c_str(), title.c_str())); } double cvGetPropWindowAutoSize_W32(const char* name) { double result = -1; - CV_FUNCNAME( "cvSetCloseCallback" ); + CV_FUNCNAME("cvSetCloseCallback"); - __BEGIN__; - - CvWindow* window; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); + auto window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); result = window->flags & CV_WINDOW_AUTOSIZE; - __END__; - return result; } @@ -724,23 +830,19 @@ double cvGetRatioWindow_W32(const char* name) { double result = -1; - CV_FUNCNAME( "cvGetRatioWindow_W32" ); + CV_FUNCNAME("cvGetRatioWindow_W32"); - __BEGIN__; - - CvWindow* window; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); + auto window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); result = static_cast(window->width) / window->height; - __END__; - return result; } @@ -749,23 +851,20 @@ double cvGetOpenGlProp_W32(const char* name) double result = -1; #ifdef HAVE_OPENGL - CV_FUNCNAME( "cvGetOpenGlProp_W32" ); + CV_FUNCNAME("cvGetOpenGlProp_W32"); - __BEGIN__; - - CvWindow* window; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); + auto window = icvFindWindowByName(name); if (!window) - EXIT; // keep silence here + return -1; result = window->useGl; - - __END__; #endif + CV_UNUSED(name); return result; @@ -775,16 +874,15 @@ double cvGetPropVisible_W32(const char* name) { double result = -1; - CV_FUNCNAME( "cvGetPropVisible_W32" ); + CV_FUNCNAME("cvGetPropVisible_W32"); - __BEGIN__; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - result = (icvFindWindowByName( name ) != NULL); + CV_Error(Error::StsNullPtr, "NULL name string"); - __END__; + auto window = icvFindWindowByName(name); + result = (bool)window ? 1.0 : 0.0; return result; } @@ -798,9 +896,9 @@ namespace { void createGlContext(HWND hWnd, HDC& hGLDC, HGLRC& hGLRC, bool& useGl) { - CV_FUNCNAME( "createGlContext" ); + CV_FUNCNAME("createGlContext"); - __BEGIN__; + AutoLock lock(getWindowMutex()); useGl = false; @@ -830,120 +928,119 @@ namespace hGLDC = GetDC(hWnd); if (!hGLDC) - CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Device Context" ); + CV_Error(Error::OpenGlApiCallError, "Can't Create A GL Device Context"); PixelFormat = ChoosePixelFormat(hGLDC, &pfd); if (!PixelFormat) - CV_ERROR( CV_OpenGlApiCallError, "Can't Find A Suitable PixelFormat" ); + CV_Error(Error::OpenGlApiCallError, "Can't Find A Suitable PixelFormat"); if (!SetPixelFormat(hGLDC, PixelFormat, &pfd)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Set The PixelFormat" ); + CV_Error(Error::OpenGlApiCallError, "Can't Set The PixelFormat"); hGLRC = wglCreateContext(hGLDC); if (!hGLRC) - CV_ERROR( CV_OpenGlApiCallError, "Can't Create A GL Rendering Context" ); + CV_Error(Error::OpenGlApiCallError, "Can't Create A GL Rendering Context"); if (!wglMakeCurrent(hGLDC, hGLRC)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context"); useGl = true; - - __END__; } - void releaseGlContext(CvWindow* window) + void releaseGlContext(CvWindow& window) { - //CV_FUNCNAME( "releaseGlContext" ); + //CV_FUNCNAME("releaseGlContext"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - if (window->hGLRC) + if (window.hGLRC) { - wglDeleteContext(window->hGLRC); - window->hGLRC = NULL; + wglDeleteContext(window.hGLRC); + window.hGLRC = NULL; } - if (window->dc) + if (window.dc) { - ReleaseDC(window->hwnd, window->dc); - window->dc = NULL; + ReleaseDC(window.hwnd, window.dc); + window.dc = NULL; } - window->useGl = false; - - __END__; + window.useGl = false; } - void drawGl(CvWindow* window) + void drawGl(CvWindow& window) { - CV_FUNCNAME( "drawGl" ); + CV_FUNCNAME("drawGl"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - if (!wglMakeCurrent(window->dc, window->hGLRC)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + if (!wglMakeCurrent(window.dc, window.hGLRC)) + CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (window->glDrawCallback) - window->glDrawCallback(window->glDrawData); - - if (!SwapBuffers(window->dc)) - CV_ERROR( CV_OpenGlApiCallError, "Can't swap OpenGL buffers" ); + if (window.glDrawCallback) + window.glDrawCallback(window.glDrawData); - __END__; + if (!SwapBuffers(window.dc)) + CV_Error(Error::OpenGlApiCallError, "Can't swap OpenGL buffers"); } - void resizeGl(CvWindow* window) + void resizeGl(CvWindow& window) { - CV_FUNCNAME( "resizeGl" ); + CV_FUNCNAME("resizeGl"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - if (!wglMakeCurrent(window->dc, window->hGLRC)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); + if (!wglMakeCurrent(window.dc, window.hGLRC)) + CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context"); - glViewport(0, 0, window->width, window->height); - - __END__; + glViewport(0, 0, window.width, window.height); } } #endif // HAVE_OPENGL +static std::shared_ptr namedWindow_(const std::string& name, int flags); + +CV_IMPL int cvNamedWindow(const char* name, int flags) +{ + CV_FUNCNAME("cvNamedWindow"); + + AutoLock lock(getWindowMutex()); + + if (!name) + CV_Error(Error::StsNullPtr, "NULL name string"); + + // Check the name in the storage + auto window = icvFindWindowByName(name); + if (window) + { + return 1; + } + + window = namedWindow_(name, flags); + return (bool)window; +} -CV_IMPL int cvNamedWindow( const char* name, int flags ) +static std::shared_ptr namedWindow_(const std::string& name, int flags) { - int result = 0; - CV_FUNCNAME( "cvNamedWindow" ); + AutoLock lock(getWindowMutex()); - __BEGIN__; + cvInitSystem(0,0); HWND hWnd, mainhWnd; - CvWindow* window; DWORD defStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU; - int len; - CvRect rect; #ifdef HAVE_OPENGL bool useGl; HDC hGLDC; HGLRC hGLRC; #endif - cvInitSystem(0,0); - - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); - - // Check the name in the storage - window = icvFindWindowByName( name ); - if (window != 0) - { - result = 1; - EXIT; - } + CvRect rect; + icvLoadWindowPos(name.c_str(), rect); - if( !(flags & CV_WINDOW_AUTOSIZE))//YV add border in order to resize the window + if (!(flags & CV_WINDOW_AUTOSIZE))//YV add border in order to resize the window defStyle |= WS_SIZEBOX; #ifdef HAVE_OPENGL @@ -951,23 +1048,21 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) defStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; #endif - icvLoadWindowPos( name, rect ); - - mainhWnd = CreateWindow( "Main HighGUI class", name, defStyle | WS_OVERLAPPED, - rect.x, rect.y, rect.width, rect.height, 0, 0, hg_hinstance, 0 ); - if( !mainhWnd ) - CV_ERROR( CV_StsError, "Frame window can not be created" ); + mainhWnd = CreateWindow(mainHighGUIclassName, name.c_str(), defStyle | WS_OVERLAPPED, + rect.x, rect.y, rect.width, rect.height, 0, 0, hg_hinstance, 0); + if (!mainhWnd) + CV_Error_(Error::StsError, ("Frame window can not be created: '%s'", name.c_str())); ShowWindow(mainhWnd, SW_SHOW); //YV- remove one border by changing the style - hWnd = CreateWindow("HighGUI class", "", (defStyle & ~WS_SIZEBOX) | WS_CHILD, CW_USEDEFAULT, 0, rect.width, rect.height, mainhWnd, 0, hg_hinstance, 0); - if( !hWnd ) - CV_ERROR( CV_StsError, "Frame window can not be created" ); + hWnd = CreateWindow(highGUIclassName, "", (defStyle & ~WS_SIZEBOX) | WS_CHILD, CW_USEDEFAULT, 0, rect.width, rect.height, mainhWnd, 0, hg_hinstance, 0); + if (!hWnd) + CV_Error(Error::StsError, "Frame window can not be created"); #ifndef HAVE_OPENGL if (flags & CV_WINDOW_OPENGL) - CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); + CV_Error(Error::OpenGlNotSupported, "Library was built without OpenGL support"); #else useGl = false; hGLDC = 0; @@ -979,14 +1074,10 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) ShowWindow(hWnd, SW_SHOW); - len = (int)strlen(name); - CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1)); + auto window = std::make_shared(name); - window->signature = CV_WINDOW_MAGIC_VAL; window->hwnd = hWnd; window->frame = mainhWnd; - window->name = (char*)(window + 1); - memcpy( window->name, name, len + 1 ); window->flags = flags; window->image = 0; @@ -1016,200 +1107,175 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) window->on_mouse = 0; window->on_mouse_param = 0; - memset( &window->toolbar, 0, sizeof(window->toolbar)); + icvSetWindowLongPtr(hWnd, CV_USERDATA, window.get()); + icvSetWindowLongPtr(mainhWnd, CV_USERDATA, window.get()); - window->next = hg_windows; - window->prev = 0; - if( hg_windows ) - hg_windows->prev = window; - hg_windows = window; - icvSetWindowLongPtr( hWnd, CV_USERDATA, window ); - icvSetWindowLongPtr( mainhWnd, CV_USERDATA, window ); + auto& g_windows = getWindowsList(); + g_windows.push_back(window); // Recalculate window pos - icvUpdateWindowPos( window ); + icvUpdateWindowPos(*window); - result = 1; - __END__; - - return result; + return window; } #ifdef HAVE_OPENGL CV_IMPL void cvSetOpenGlContext(const char* name) { - CV_FUNCNAME( "cvSetOpenGlContext" ); - - __BEGIN__; + CV_FUNCNAME("cvSetOpenGlContext"); - CvWindow* window; + AutoLock lock(getWindowMutex()); - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + if (!name) + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); + auto window = icvFindWindowByName(name); if (!window) - CV_ERROR( CV_StsNullPtr, "NULL window" ); + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); if (!window->useGl) - CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); + CV_Error(Error::OpenGlNotSupported, "Window doesn't support OpenGL"); if (!wglMakeCurrent(window->dc, window->hGLRC)) - CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); - - __END__; + CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context"); } CV_IMPL void cvUpdateWindow(const char* name) { - CV_FUNCNAME( "cvUpdateWindow" ); - - __BEGIN__; + CV_FUNCNAME("cvUpdateWindow"); - CvWindow* window; + AutoLock lock(getWindowMutex()); if (!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); + auto window = icvFindWindowByName(name); if (!window) - EXIT; + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); InvalidateRect(window->hwnd, 0, 0); - - __END__; } CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback callback, void* userdata) { - CV_FUNCNAME( "cvCreateOpenGLCallback" ); - - __BEGIN__; + CV_FUNCNAME("cvCreateOpenGLCallback"); - CvWindow* window; + AutoLock lock(getWindowMutex()); - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + if (!name) + CV_Error(Error::StsNullPtr, "NULL name string"); - window = icvFindWindowByName( name ); - if( !window ) - EXIT; + auto window = icvFindWindowByName(name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); if (!window->useGl) - CV_ERROR( CV_OpenGlNotSupported, "Window was created without OpenGL context" ); + CV_Error(Error::OpenGlNotSupported, "Window was created without OpenGL context"); window->glDrawCallback = callback; window->glDrawData = userdata; - - __END__; } #endif // HAVE_OPENGL -static void icvRemoveWindow( CvWindow* window ) +static void icvRemoveWindow(const std::shared_ptr& window_) { - CvTrackbar* trackbar = NULL; + CV_Assert(window_); + AutoLock lock(getWindowMutex()); + CvWindow& window = *window_; + RECT wrect={0,0,0,0}; + auto& g_windows = getWindowsList(); + for (auto it = g_windows.begin(); it != g_windows.end(); ++it) + { + const std::shared_ptr& w = *it; + if (w.get() == &window) + { + g_windows.erase(it); + break; + } + } + #ifdef HAVE_OPENGL - if (window->useGl) + if (window.useGl) releaseGlContext(window); #endif - if( window->frame ) - GetWindowRect( window->frame, &wrect ); - if( window->name ) - icvSaveWindowPos( window->name, cvRect(wrect.left, wrect.top, - wrect.right-wrect.left, wrect.bottom-wrect.top) ); - - if( window->hwnd ) - icvSetWindowLongPtr( window->hwnd, CV_USERDATA, 0 ); - if( window->frame ) - icvSetWindowLongPtr( window->frame, CV_USERDATA, 0 ); - - if( window->toolbar.toolbar ) - icvSetWindowLongPtr(window->toolbar.toolbar, CV_USERDATA, 0); - - if( window->prev ) - window->prev->next = window->next; - else - hg_windows = window->next; + if (window.frame) + GetWindowRect(window.frame, &wrect); + icvSaveWindowPos(window.name.c_str(), cvRect(wrect.left, wrect.top, wrect.right-wrect.left, wrect.bottom-wrect.top)); - if( window->next ) - window->next->prev = window->prev; + if (window.hwnd) + icvSetWindowLongPtr(window.hwnd, CV_USERDATA, 0); + if (window.frame) + icvSetWindowLongPtr(window.frame, CV_USERDATA, 0); - window->prev = window->next = 0; + if (window.toolbar.toolbar) + icvSetWindowLongPtr(window.toolbar.toolbar, CV_USERDATA, 0); - if( window->dc && window->image ) - DeleteObject(SelectObject(window->dc,window->image)); + if (window.dc && window.image) + DeleteObject(SelectObject(window.dc, window.image)); - if( window->dc ) - DeleteDC(window->dc); + if (window.dc) + DeleteDC(window.dc); - for( trackbar = window->toolbar.first; trackbar != 0; ) + for (auto it = window.toolbar.trackbars.begin(); it != window.toolbar.trackbars.end(); ++it) { - CvTrackbar* next = trackbar->next; - if( trackbar->hwnd ) + auto trackbar = (*it).get(); + if (trackbar && trackbar->hwnd) { - icvSetWindowLongPtr( trackbar->hwnd, CV_USERDATA, 0 ); - cvFree( &trackbar ); + icvSetWindowLongPtr(trackbar->hwnd, CV_USERDATA, 0); } - trackbar = next; } - - cvFree( &window ); } -CV_IMPL void cvDestroyWindow( const char* name ) +CV_IMPL void cvDestroyWindow(const char* name) { - CV_FUNCNAME( "cvDestroyWindow" ); + CV_FUNCNAME("cvDestroyWindow"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - CvWindow* window; - HWND mainhWnd; + if (!name) + CV_Error(Error::StsNullPtr, "NULL name string"); - if(!name) - CV_ERROR( CV_StsNullPtr, "NULL name string" ); + auto window = icvFindWindowByName(name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - window = icvFindWindowByName( name ); - if( !window ) - EXIT; + window->destroy(); +} - mainhWnd = window->frame; - SendMessage(window->hwnd, WM_CLOSE, 0, 0); - SendMessage( mainhWnd, WM_CLOSE, 0, 0); +void CvWindow::destroy() +{ + SendMessage(hwnd, WM_CLOSE, 0, 0); + SendMessage(frame, WM_CLOSE, 0, 0); // Do NOT call _remove_window -- CvWindow list will be updated automatically ... - - __END__; } - -static void icvScreenToClient( HWND hwnd, RECT* rect ) +static void icvScreenToClient(HWND hwnd, RECT* rect) { POINT p; p.x = rect->left; p.y = rect->top; ScreenToClient(hwnd, &p); - OffsetRect( rect, p.x - rect->left, p.y - rect->top ); + OffsetRect(rect, p.x - rect->left, p.y - rect->top); } /* Calculatess the window coordinates relative to the upper left corner of the mainhWnd window */ -static RECT icvCalcWindowRect( CvWindow* window ) +static RECT icvCalcWindowRect(CvWindow& window) { RECT crect = { 0 }, trect = { 0 }, rect = { 0 }; - assert(window); - - GetClientRect(window->frame, &crect); - if (window->toolbar.toolbar) + GetClientRect(window.frame, &crect); + if (window.toolbar.toolbar) { - GetWindowRect(window->toolbar.toolbar, &trect); - icvScreenToClient(window->frame, &trect); + GetWindowRect(window.toolbar.toolbar, &trect); + icvScreenToClient(window.frame, &trect); SubtractRect(&rect, &crect, &trect); } else @@ -1217,138 +1283,153 @@ static RECT icvCalcWindowRect( CvWindow* window ) return rect; } +static inline RECT icvCalcWindowRect(CvWindow* window) { CV_Assert(window); return icvCalcWindowRect(*window); } + -// returns TRUE if there is a problem such as ERROR_IO_PENDING. -static bool icvGetBitmapData( CvWindow* window, SIZE* size, int* channels, void** data ) +// returns FALSE if there is a problem such as ERROR_IO_PENDING. +static bool icvGetBitmapData(CvWindow& window, SIZE& size, int& channels, void*& data) { - BITMAP bmp; GdiFlush(); - HGDIOBJ h = GetCurrentObject( window->dc, OBJ_BITMAP ); - if( size ) - size->cx = size->cy = 0; - if( data ) - *data = 0; + + HGDIOBJ h = GetCurrentObject(window.dc, OBJ_BITMAP); + size.cx = size.cy = 0; + data = 0; if (h == NULL) - return true; + return false; + + BITMAP bmp = {}; if (GetObject(h, sizeof(bmp), &bmp) == 0) - return true; + return false; - if( size ) - { - size->cx = abs(bmp.bmWidth); - size->cy = abs(bmp.bmHeight); - } + size.cx = abs(bmp.bmWidth); + size.cy = abs(bmp.bmHeight); - if( channels ) - *channels = bmp.bmBitsPixel/8; + channels = bmp.bmBitsPixel/8; - if( data ) - *data = bmp.bmBits; + data = bmp.bmBits; - return false; + return true; +} +static bool icvGetBitmapData(CvWindow& window, SIZE& size) +{ + int channels = 0; + void* data = nullptr; + return icvGetBitmapData(window, size, channels, data); } -static void icvUpdateWindowPos( CvWindow* window ) +static void icvUpdateWindowPos(CvWindow& window) { RECT rect = { 0 }; - assert(window); - if( (window->flags & CV_WINDOW_AUTOSIZE) && window->image ) + if ((window.flags & CV_WINDOW_AUTOSIZE) && window.image) { int i; SIZE size = {0,0}; - icvGetBitmapData( window, &size, 0, 0 ); + icvGetBitmapData(window, size); // TODO check return value? // Repeat two times because after the first resizing of the mainhWnd window // toolbar may resize too - for(i = 0; i < (window->toolbar.toolbar ? 2 : 1); i++) + for(i = 0; i < (window.toolbar.toolbar ? 2 : 1); i++) { - RECT rmw = { 0 }, rw = icvCalcWindowRect(window ); - MoveWindow(window->hwnd, rw.left, rw.top, + RECT rmw = { 0 }, rw = icvCalcWindowRect(&window); + MoveWindow(window.hwnd, rw.left, rw.top, rw.right - rw.left, rw.bottom - rw.top, FALSE); - GetClientRect(window->hwnd, &rw); - GetWindowRect(window->frame, &rmw); + GetClientRect(window.hwnd, &rw); + GetWindowRect(window.frame, &rmw); // Resize the mainhWnd window in order to make the bitmap fit into the child window - MoveWindow(window->frame, rmw.left, rmw.top, + MoveWindow(window.frame, rmw.left, rmw.top, size.cx + (rmw.right - rmw.left) - (rw.right - rw.left), - size.cy + (rmw.bottom - rmw.top) - (rw.bottom - rw.top), TRUE ); + size.cy + (rmw.bottom - rmw.top) - (rw.bottom - rw.top), TRUE); } } rect = icvCalcWindowRect(window); - MoveWindow(window->hwnd, rect.left, rect.top, + MoveWindow(window.hwnd, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE ); + rect.bottom - rect.top, TRUE); } +static void showImage_(CvWindow& window, const Mat& image); + CV_IMPL void -cvShowImage( const char* name, const CvArr* arr ) +cvShowImage(const char* name, const CvArr* arr) { - CV_FUNCNAME( "cvShowImage" ); - - __BEGIN__; - - CvWindow* window; - SIZE size = { 0, 0 }; - int channels = 0; - void* dst_ptr = 0; - const int channels0 = 3; - CvMat stub, *image; - bool changed_size = false; // philipg + CV_FUNCNAME("cvShowImage"); - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name" ); + if (!name) + CV_Error(Error::StsNullPtr, "NULL name"); - window = icvFindWindowByName(name); - if(!window) + std::shared_ptr window; { - cvNamedWindow(name, CV_WINDOW_AUTOSIZE); + AutoLock lock(getWindowMutex()); + window = icvFindWindowByName(name); + if (!window) + { + cvNamedWindow(name, CV_WINDOW_AUTOSIZE); + window = icvFindWindowByName(name); + } } - if( !window || !arr ) - EXIT; // keep silence here. - - CV_CALL( image = cvGetMat( arr, &stub )); + if (!window || !arr) + return; // keep silence here. + CvMat stub = {}; + CvMat* image_c = cvGetMat(arr, &stub); + Mat image = cv::cvarrToMat(image_c); #ifdef HAVE_OPENGL if (window->useGl) { - cv::imshow(name, cv::cvarrToMat(image)); + cv::imshow(name, image); return; } #endif + return showImage_(*window, image); +} + +static void showImage_(CvWindow& window, const Mat& image) +{ + AutoLock lock(window.mutex); + + SIZE size = { 0, 0 }; + int channels = 0; + void* dst_ptr = 0; + const int channels0 = 3; + bool changed_size = false; // philipg - if (window->image) + if (window.image) + { // if there is something wrong with these system calls, we cannot display image... - if (icvGetBitmapData( window, &size, &channels, &dst_ptr )) + if (!icvGetBitmapData(window, size, channels, dst_ptr)) return; + } - if( size.cx != image->width || size.cy != image->height || channels != channels0 ) + if (size.cx != image.cols || size.cy != image.rows || channels != channels0) { changed_size = true; uchar buffer[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)]; BITMAPINFO* binfo = (BITMAPINFO*)buffer; - DeleteObject( SelectObject( window->dc, window->image )); - window->image = 0; + DeleteObject(SelectObject(window.dc, window.image)); + window.image = 0; - size.cx = image->width; - size.cy = image->height; + size.cx = image.cols; + size.cy = image.rows; channels = channels0; - FillBitmapInfo( binfo, size.cx, size.cy, channels*8, 1 ); + FillBitmapInfo(binfo, size.cx, size.cy, channels*8, 1); - window->image = SelectObject( window->dc, CreateDIBSection(window->dc, binfo, - DIB_RGB_COLORS, &dst_ptr, 0, 0)); + window.image = SelectObject(window.dc, + CreateDIBSection(window.dc, binfo, DIB_RGB_COLORS, &dst_ptr, 0, 0) + ); } { cv::Mat dst(size.cy, size.cx, CV_8UC3, dst_ptr, (size.cx * channels + 3) & -4); - convertToShow(cv::cvarrToMat(image), dst, false); + convertToShow(image, dst, false); CV_Assert(dst.data == (uchar*)dst_ptr); cv::flip(dst, dst, 0); } @@ -1356,98 +1437,103 @@ cvShowImage( const char* name, const CvArr* arr ) // only resize window if needed if (changed_size) icvUpdateWindowPos(window); - InvalidateRect(window->hwnd, 0, 0); + InvalidateRect(window.hwnd, 0, 0); // philipg: this is not needed and just slows things down // UpdateWindow(window->hwnd); - - __END__; } -CV_IMPL void cvResizeWindow(const char* name, int width, int height ) +static void resizeWindow_(CvWindow& window, const Size& size); + +CV_IMPL void cvResizeWindow(const char* name, int width, int height) { - CV_FUNCNAME( "cvResizeWindow" ); + CV_FUNCNAME("cvResizeWindow"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - int i; - CvWindow* window; - RECT rmw = { 0 }, rw = { 0 }, rect = { 0 }; + if (!name) + CV_Error(Error::StsNullPtr, "NULL name"); - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name" ); + auto window = icvFindWindowByName(name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - window = icvFindWindowByName(name); - if(!window) - EXIT; + return resizeWindow_(*window, Size(width, height)); +} + +static void resizeWindow_(CvWindow& window, const Size& size) +{ + RECT rmw = { 0 }, rw = { 0 }, rect = { 0 }; // Repeat two times because after the first resizing of the mainhWnd window // toolbar may resize too - for(i = 0; i < (window->toolbar.toolbar ? 2 : 1); i++) + for (int i = 0; i < (window.toolbar.toolbar ? 2 : 1); i++) { rw = icvCalcWindowRect(window); - MoveWindow(window->hwnd, rw.left, rw.top, + MoveWindow(window.hwnd, rw.left, rw.top, rw.right - rw.left, rw.bottom - rw.top, FALSE); - GetClientRect(window->hwnd, &rw); - GetWindowRect(window->frame, &rmw); + GetClientRect(window.hwnd, &rw); + GetWindowRect(window.frame, &rmw); // Resize the mainhWnd window in order to make the bitmap fit into the child window - MoveWindow(window->frame, rmw.left, rmw.top, - width + (rmw.right - rmw.left) - (rw.right - rw.left), - height + (rmw.bottom - rmw.top) - (rw.bottom - rw.top), TRUE); + MoveWindow(window.frame, rmw.left, rmw.top, + size.width + (rmw.right - rmw.left) - (rw.right - rw.left), + size.height + (rmw.bottom - rmw.top) - (rw.bottom - rw.top), TRUE); } rect = icvCalcWindowRect(window); - MoveWindow(window->hwnd, rect.left, rect.top, + MoveWindow(window.hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); - - __END__; } +static void moveWindow_(CvWindow& window, const Point& pt); -CV_IMPL void cvMoveWindow( const char* name, int x, int y ) +CV_IMPL void cvMoveWindow(const char* name, int x, int y) { - CV_FUNCNAME( "cvMoveWindow" ); + CV_FUNCNAME("cvMoveWindow"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - CvWindow* window; - RECT rect = { 0 }; - - if( !name ) - CV_ERROR( CV_StsNullPtr, "NULL name" ); + if (!name) + CV_Error(Error::StsNullPtr, "NULL name"); - window = icvFindWindowByName(name); - if(!window) - EXIT; + auto window = icvFindWindowByName(name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); - GetWindowRect( window->frame, &rect ); - MoveWindow( window->frame, x, y, rect.right - rect.left, rect.bottom - rect.top, TRUE); + (void)moveWindow_(*window, Point(x, y)); +} - __END__; +static void moveWindow_(CvWindow& window, const Point& pt) +{ + RECT rect = { 0 }; + GetWindowRect(window.frame, &rect); // TODO check return value + MoveWindow(window.frame, pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top, TRUE); } static LRESULT CALLBACK -MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - CvWindow* window = icvWindowByHWND( hwnd ); - if( !window ) + auto window_ = icvWindowByHWND(hwnd); + if (!window_) return DefWindowProc(hwnd, uMsg, wParam, lParam); + CvWindow& window = *window_; + switch(uMsg) { case WM_COPY: - ::SendMessage(window->hwnd, uMsg, wParam, lParam); + ::SendMessage(window.hwnd, uMsg, wParam, lParam); break; case WM_DESTROY: - icvRemoveWindow(window); + icvRemoveWindow(window_); // Do nothing!!! //PostQuitMessage(0); break; case WM_GETMINMAXINFO: - if( !(window->flags & CV_WINDOW_AUTOSIZE) ) + if (!(window.flags & CV_WINDOW_AUTOSIZE)) { MINMAXINFO* minmax = (MINMAXINFO*)lParam; RECT rect = { 0 }; @@ -1456,10 +1542,10 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) minmax->ptMinTrackSize.y = 100; minmax->ptMinTrackSize.x = 100; - if( window->toolbar.first ) + if (!window.toolbar.trackbars.empty()) { - GetWindowRect( window->toolbar.first->hwnd, &rect ); - minmax->ptMinTrackSize.y += window->toolbar.rows*(rect.bottom - rect.top); + GetWindowRect(window.toolbar.trackbars[0]->hwnd, &rect); + minmax->ptMinTrackSize.y += window.toolbar.rows*(rect.bottom - rect.top); minmax->ptMinTrackSize.x = MAX(rect.right - rect.left + HG_BUDDY_WIDTH, HG_BUDDY_WIDTH*2); } return retval; @@ -1471,14 +1557,14 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) WINDOWPOS* pos = (WINDOWPOS*)lParam; // Update the toolbar pos/size - if(window->toolbar.toolbar) + if (window.toolbar.toolbar) { RECT rect = { 0 }; - GetWindowRect(window->toolbar.toolbar, &rect); - MoveWindow(window->toolbar.toolbar, 0, 0, pos->cx, rect.bottom - rect.top, TRUE); + GetWindowRect(window.toolbar.toolbar, &rect); + MoveWindow(window.toolbar.toolbar, 0, 0, pos->cx, rect.bottom - rect.top, TRUE); } - if(!(window->flags & CV_WINDOW_AUTOSIZE)) + if (!(window.flags & CV_WINDOW_AUTOSIZE)) icvUpdateWindowPos(window); break; @@ -1490,7 +1576,7 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) LPWINDOWPOS pos = (LPWINDOWPOS)lParam; RECT rect = { 0 }; - GetWindowRect(window->frame, &rect); + GetWindowRect(window.frame, &rect); HMONITOR hMonitor; hMonitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST); @@ -1515,13 +1601,13 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) } case WM_ACTIVATE: - if(LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) - SetFocus(window->hwnd); + if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) + SetFocus(window.hwnd); break; case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: - if( window->on_mouse ) + if (window.on_mouse) { int flags = (wParam & MK_LBUTTON ? CV_EVENT_FLAG_LBUTTON : 0)| (wParam & MK_RBUTTON ? CV_EVENT_FLAG_RBUTTON : 0)| @@ -1536,32 +1622,32 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) flags |= (delta << 16); POINT pt; - pt.x = GET_X_LPARAM( lParam ); - pt.y = GET_Y_LPARAM( lParam ); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); ::ScreenToClient(hwnd, &pt); // Convert screen coordinates to client coordinates. RECT rect = { 0 }; - GetClientRect( window->hwnd, &rect ); + GetClientRect(window.hwnd, &rect); SIZE size = {0,0}; #ifdef HAVE_OPENGL - if (window->useGl) + if (window.useGl) { - cv::ogl::Texture2D* texObj = static_cast(window->glDrawData); + cv::ogl::Texture2D* texObj = static_cast(window.glDrawData); size.cx = texObj->cols(); size.cy = texObj->rows(); } else { - icvGetBitmapData(window, &size, 0, 0); + icvGetBitmapData(window, size); } #else - icvGetBitmapData(window, &size, 0, 0); + icvGetBitmapData(window, size); #endif - window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1), - pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags, - window->on_mouse_param ); + int x = cvRound((float)pt.x*size.cx/MAX(rect.right - rect.left,1)); + int y = cvRound((float)pt.y*size.cy/MAX(rect.bottom - rect.top,1)); + window.on_mouse(event, x, y, flags, window.on_mouse_param); } break; @@ -1571,17 +1657,17 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) HRGN rgn, rgn1, rgn2; int ret; HDC hdc = (HDC)wParam; - GetWindowRect(window->hwnd, &cr); - icvScreenToClient(window->frame, &cr); - if(window->toolbar.toolbar) + GetWindowRect(window.hwnd, &cr); + icvScreenToClient(window.frame, &cr); + if (window.toolbar.toolbar) { - GetWindowRect(window->toolbar.toolbar, &tr); - icvScreenToClient(window->frame, &tr); + GetWindowRect(window.toolbar.toolbar, &tr); + icvScreenToClient(window.frame, &tr); } else tr.left = tr.top = tr.right = tr.bottom = 0; - GetClientRect(window->frame, &wrc); + GetClientRect(window.frame, &wrc); rgn = CreateRectRgn(0, 0, wrc.right, wrc.bottom); rgn1 = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom); @@ -1591,7 +1677,7 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) ret = CombineRgn(rgn, rgn, rgn1, RGN_DIFF); ret = CombineRgn(rgn, rgn, rgn2, RGN_DIFF); - if(ret != NULLREGION && ret != ERROR) + if (ret != NULLREGION && ret != ERROR) FillRgn(hdc, rgn, (HBRUSH)icvGetClassLongPtr(hwnd, CV_HBRBACKGROUND)); DeleteObject(rgn); @@ -1605,20 +1691,24 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) } -static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +static LRESULT CALLBACK HighGUIProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - CvWindow* window = icvWindowByHWND(hwnd); - if( !window ) + auto window_ = icvWindowByHWND(hwnd); + if (!window_) + { // This window is not mentioned in HighGUI storage // Actually, this should be error except for the case of calls to CreateWindow return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + + CvWindow& window = *window_; // Process the message switch(uMsg) { case WM_COPY: { - if (!::OpenClipboard(hwnd) ) + if (!::OpenClipboard(hwnd)) break; HDC hDC = 0; @@ -1632,7 +1722,7 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM if (!::EmptyClipboard()) break; - if(!window->image) + if (!window.image) break; // Get window device context @@ -1640,19 +1730,20 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM break; // Create another DC compatible with hDC - if (0 == (memDC = ::CreateCompatibleDC( hDC ))) + if (0 == (memDC = ::CreateCompatibleDC(hDC))) break; // Determine the bitmap's dimensions - int nchannels = 3; SIZE size = {0,0}; - icvGetBitmapData( window, &size, &nchannels, 0 ); + int nchannels = 3; + void* data = NULL; // unused + icvGetBitmapData(window, size, nchannels, data); // Create bitmap to draw on and it in the new DC - if (0 == (memBM = ::CreateCompatibleBitmap ( hDC, size.cx, size.cy))) + if (0 == (memBM = ::CreateCompatibleBitmap(hDC, size.cx, size.cy))) break; - if (!::SelectObject( memDC, memBM )) + if (!::SelectObject(memDC, memBM)) break; // Begin drawing to DC @@ -1660,7 +1751,7 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM break; RGBQUAD table[256]; - if( 1 == nchannels ) + if (1 == nchannels) { for(int i = 0; i < 256; ++i) { @@ -1668,14 +1759,14 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM table[i].rgbGreen = (unsigned char)i; table[i].rgbRed = (unsigned char)i; } - if (!::SetDIBColorTable(window->dc, 0, 255, table)) + if (!::SetDIBColorTable(window.dc, 0, 255, table)) break; } // The image copied to the clipboard will be in its original size, regardless if the window itself was resized. // Render the image to the dc/bitmap (at original size). - if (!::BitBlt( memDC, 0, 0, size.cx, size.cy, window->dc, 0, 0, SRCCOPY )) + if (!::BitBlt(memDC, 0, 0, size.cx, size.cy, window.dc, 0, 0, SRCCOPY)) break; // Finally, set bitmap to clipboard @@ -1712,7 +1803,7 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_MOUSEMOVE: - if( window->on_mouse ) + if (window.on_mouse) { POINT pt; @@ -1732,50 +1823,50 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM uMsg == WM_RBUTTONDBLCLK ? CV_EVENT_RBUTTONDBLCLK : uMsg == WM_MBUTTONDBLCLK ? CV_EVENT_MBUTTONDBLCLK : CV_EVENT_MOUSEMOVE; - if( uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN ) - SetCapture( hwnd ); - if( uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_MBUTTONUP ) + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN) + SetCapture(hwnd); + if (uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_MBUTTONUP) ReleaseCapture(); - pt.x = GET_X_LPARAM( lParam ); - pt.y = GET_Y_LPARAM( lParam ); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); - if (window->flags & CV_WINDOW_AUTOSIZE) + if (window.flags & CV_WINDOW_AUTOSIZE) { // As user can't change window size, do not scale window coordinates. Underlying windowing system // may prevent full window from being displayed and in this case coordinates should not be scaled. - window->on_mouse( event, pt.x, pt.y, flags, window->on_mouse_param ); + window.on_mouse(event, pt.x, pt.y, flags, window.on_mouse_param); } else { // Full window is displayed using different size. Scale coordinates to match underlying positions. RECT rect = { 0 }; SIZE size = {0, 0}; - GetClientRect( window->hwnd, &rect ); + GetClientRect(window.hwnd, &rect); #ifdef HAVE_OPENGL - if (window->useGl) + if (window.useGl) { - cv::ogl::Texture2D* texObj = static_cast(window->glDrawData); + cv::ogl::Texture2D* texObj = static_cast(window.glDrawData); size.cx = texObj->cols(); size.cy = texObj->rows(); } else { - icvGetBitmapData(window, &size, 0, 0); + icvGetBitmapData(window, size); } #else - icvGetBitmapData( window, &size, 0, 0 ); + icvGetBitmapData(window, size); #endif - window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1), - pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags, - window->on_mouse_param ); + int x = cvRound((float)pt.x*size.cx/MAX(rect.right - rect.left,1)); + int y = cvRound((float)pt.y*size.cy/MAX(rect.bottom - rect.top,1)); + window.on_mouse(event, x, y, flags, window.on_mouse_param); } } break; case WM_PAINT: - if(window->image != 0) + if (window.image != 0) { int nchannels = 3; SIZE size = {0,0}; @@ -1784,12 +1875,13 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM RGBQUAD table[256]; // Determine the bitmap's dimensions - icvGetBitmapData( window, &size, &nchannels, 0 ); + void* data = 0; // unused + icvGetBitmapData(window, size, nchannels, data); hdc = BeginPaint(hwnd, &paint); SetStretchBltMode(hdc, COLORONCOLOR); - if( nchannels == 1 ) + if (nchannels == 1) { int i; for(i = 0; i < 256; i++) @@ -1798,25 +1890,25 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM table[i].rgbGreen = (unsigned char)i; table[i].rgbRed = (unsigned char)i; } - SetDIBColorTable(window->dc, 0, 255, table); + SetDIBColorTable(window.dc, 0, 255, table); } - if(window->flags & CV_WINDOW_AUTOSIZE) + if (window.flags & CV_WINDOW_AUTOSIZE) { - BitBlt( hdc, 0, 0, size.cx, size.cy, window->dc, 0, 0, SRCCOPY ); + BitBlt(hdc, 0, 0, size.cx, size.cy, window.dc, 0, 0, SRCCOPY); } else { RECT rect = { 0 }; - GetClientRect(window->hwnd, &rect); - StretchBlt( hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, - window->dc, 0, 0, size.cx, size.cy, SRCCOPY ); + GetClientRect(window.hwnd, &rect); + StretchBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, + window.dc, 0, 0, size.cx, size.cy, SRCCOPY); } //DeleteDC(hdc); EndPaint(hwnd, &paint); } #ifdef HAVE_OPENGL - else if(window->useGl) + else if (window.useGl) { drawGl(window); return DefWindowProc(hwnd, uMsg, wParam, lParam); @@ -1829,13 +1921,13 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM return 0; case WM_ERASEBKGND: - if(window->image) + if (window.image) return 0; break; case WM_DESTROY: - icvRemoveWindow(window); + icvRemoveWindow(window_); // Do nothing!!! //PostQuitMessage(0); break; @@ -1845,15 +1937,15 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM return 0; case WM_KEYDOWN: - window->last_key = (int)wParam; + window.last_key = (int)wParam; return 0; case WM_SIZE: - window->width = LOWORD(lParam); - window->height = HIWORD(lParam); + window.width = LOWORD(lParam); + window.height = HIWORD(lParam); #ifdef HAVE_OPENGL - if (window->useGl) + if (window.useGl) resizeGl(window); #endif } @@ -1862,24 +1954,24 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM } -static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT ret; - if( hg_on_preprocess ) + if (hg_on_preprocess) { int was_processed = 0; int rethg = hg_on_preprocess(hwnd, uMsg, wParam, lParam, &was_processed); - if( was_processed ) + if (was_processed) return rethg; } ret = HighGUIProc(hwnd, uMsg, wParam, lParam); - if(hg_on_postprocess) + if (hg_on_postprocess) { int was_processed = 0; int rethg = hg_on_postprocess(hwnd, uMsg, wParam, lParam, &was_processed); - if( was_processed ) + if (was_processed) return rethg; } @@ -1887,51 +1979,56 @@ static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM } -static void icvUpdateTrackbar( CvTrackbar* trackbar, int pos ) +static void icvUpdateTrackbar(CvTrackbar& trackbar, int pos) { const int max_name_len = 10; const char* suffix = ""; char pos_text[32]; int name_len; - if( trackbar->data ) - *trackbar->data = pos; + if (trackbar.data) + *trackbar.data = pos; - if( trackbar->pos != pos ) + if (trackbar.pos != pos) { - trackbar->pos = pos; - if( trackbar->notify2 ) - trackbar->notify2(pos, trackbar->userdata); - if( trackbar->notify ) - trackbar->notify(pos); - - name_len = (int)strlen(trackbar->name); - - if( name_len > max_name_len ) + trackbar.pos = pos; + if (trackbar.onChangeCallback) + trackbar.onChangeCallback(pos, trackbar.userdata); + if (trackbar.notify2) + trackbar.notify2(pos, trackbar.userdata); + if (trackbar.notify) + trackbar.notify(pos); + + name_len = (int)trackbar.name.size(); + + // TODO replace C strings manipulation + if (name_len > max_name_len) { int start_len = max_name_len*2/3; int end_len = max_name_len - start_len - 2; - memcpy( pos_text, trackbar->name, start_len ); - memcpy( pos_text + start_len, "...", 3 ); - memcpy( pos_text + start_len + 3, trackbar->name + name_len - end_len, end_len + 1 ); + memcpy(pos_text, trackbar.name.c_str(), start_len); + memcpy(pos_text + start_len, "...", 3); + memcpy(pos_text + start_len + 3, trackbar.name.c_str() + name_len - end_len, end_len + 1); } else { - memcpy( pos_text, trackbar->name, name_len + 1); + memcpy(pos_text, trackbar.name.c_str(), name_len + 1); } - sprintf( pos_text + strlen(pos_text), "%s: %d\n", suffix, pos ); - SetWindowText( trackbar->buddy, pos_text ); + sprintf(pos_text + strlen(pos_text), "%s: %d\n", suffix, pos); + SetWindowText(trackbar.buddy, pos_text); } } -static LRESULT CALLBACK HGToolbarProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +static LRESULT CALLBACK HGToolbarProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - CvWindow* window = icvWindowByHWND( hwnd ); - if(!window) + auto window_ = icvWindowByHWND(hwnd); + if (!window_) return DefWindowProc(hwnd, uMsg, wParam, lParam); + CvWindow& window = *window_; + // Control messages processing switch(uMsg) { @@ -1940,32 +2037,34 @@ static LRESULT CALLBACK HGToolbarProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPAR { HWND slider = (HWND)lParam; int pos = (int)SendMessage(slider, TBM_GETPOS, 0, 0); - CvTrackbar* trackbar = icvTrackbarByHWND( slider ); + auto trackbar = icvTrackbarByHWND(slider); - if( trackbar ) + if (trackbar) { - if( trackbar->pos != pos ) - icvUpdateTrackbar( trackbar, pos ); + if (trackbar->pos != pos) + icvUpdateTrackbar(*trackbar, pos); } - SetFocus( window->hwnd ); + SetFocus(window.hwnd); return 0; } case WM_NCCALCSIZE: { - LRESULT ret = CallWindowProc(window->toolbar.toolBarProc, hwnd, uMsg, wParam, lParam); + LRESULT ret = CallWindowProc(window.toolbar.toolBarProc, hwnd, uMsg, wParam, lParam); int rows = (int)SendMessage(hwnd, TB_GETROWS, 0, 0); - if(window->toolbar.rows != rows) + if (window.toolbar.rows != rows) { - SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); - CvTrackbar* trackbar = window->toolbar.first; + SendMessage(window.toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + auto& trakbars = window.toolbar.trackbars; - for( ; trackbar != 0; trackbar = trackbar->next ) + for (auto it = trakbars.begin(); it != trakbars.end(); ++it) { + auto trackbar = *it; + CV_Assert(trackbar); RECT rect = { 0 }; - SendMessage(window->toolbar.toolbar, TB_GETITEMRECT, + SendMessage(window.toolbar.toolbar, TB_GETITEMRECT, (WPARAM)trackbar->id, (LPARAM)&rect); MoveWindow(trackbar->hwnd, rect.left + HG_BUDDY_WIDTH, rect.top, rect.right - rect.left - HG_BUDDY_WIDTH, @@ -1973,46 +2072,63 @@ static LRESULT CALLBACK HGToolbarProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPAR MoveWindow(trackbar->buddy, rect.left, rect.top, HG_BUDDY_WIDTH, rect.bottom - rect.top, FALSE); } - window->toolbar.rows = rows; + window.toolbar.rows = rows; } return ret; } } - return CallWindowProc(window->toolbar.toolBarProc, hwnd, uMsg, wParam, lParam); + return CallWindowProc(window.toolbar.toolBarProc, hwnd, uMsg, wParam, lParam); } CV_IMPL void cvDestroyAllWindows(void) { - CvWindow* window = hg_windows; - - while( window ) + std::vector< std::shared_ptr > g_windows; + { + AutoLock lock(getWindowMutex()); + g_windows = getWindowsList(); // copy + } + for (auto it = g_windows.begin(); it != g_windows.end(); ++it) { - HWND mainhWnd = window->frame; - HWND hwnd = window->hwnd; - window = window->next; + auto window_ = *it; + if (!window_) + continue; + + { + CvWindow& window = *window_; + + HWND mainhWnd = window.frame; + HWND hwnd = window.hwnd; - SendMessage( hwnd, WM_CLOSE, 0, 0 ); - SendMessage( mainhWnd, WM_CLOSE, 0, 0 ); + SendMessage(hwnd, WM_CLOSE, 0, 0); + SendMessage(mainhWnd, WM_CLOSE, 0, 0); + } + + window_.reset(); + } + // TODO needed? + { + AutoLock lock(getWindowMutex()); + getWindowsList().clear(); } } -static void showSaveDialog(CvWindow* window) +static void showSaveDialog(CvWindow& window) { - if (!window || !window->image) + if (!window.image) return; SIZE sz; int channels; void* data; - if (icvGetBitmapData(window, &sz, &channels, &data)) + if (!icvGetBitmapData(window, sz, channels, data)) return; // nothing to save char szFileName[MAX_PATH] = ""; // try to use window title as file name - GetWindowText(window->frame, szFileName, MAX_PATH); + GetWindowText(window.frame, szFileName, MAX_PATH); OPENFILENAME ofn; ZeroMemory(&ofn, sizeof(ofn)); @@ -2022,7 +2138,7 @@ static void showSaveDialog(CvWindow* window) #else ofn.lStructSize = sizeof(ofn); #endif - ofn.hwndOwner = window->hwnd; + ofn.hwndOwner = window.hwnd; ofn.lpstrFilter = #ifdef HAVE_PNG "Portable Network Graphics files (*.png)\0*.png\0" @@ -2075,15 +2191,22 @@ static bool handleMessage(MSG& message, int& keyCode) // otherwise the message was handled specifically bool is_processed = false; - for (CvWindow* window = hg_windows; window != 0 && is_processed == 0; window = window->next) + AutoLock lock(getWindowMutex()); + auto& g_windows = getWindowsList(); + for (auto it = g_windows.begin(); it != g_windows.end() && !is_processed; ++it) { - if (!(window->hwnd == message.hwnd || window->frame == message.hwnd)) + auto window_ = *it; + if (!window_) + continue; + CvWindow& window = *window_; + if (!(window.hwnd == message.hwnd || window.frame == message.hwnd)) continue; is_processed = true; switch (message.message) { case WM_DESTROY: + // fallthru case WM_CHAR: DispatchMessage(&message); keyCode = (int)message.wParam; @@ -2099,6 +2222,20 @@ static bool handleMessage(MSG& message, int& keyCode) break; case WM_KEYDOWN: + // Intercept Ctrl+C for copy to clipboard + if ('C' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15)) + { + ::SendMessage(message.hwnd, WM_COPY, 0, 0); + return false; + } + + // Intercept Ctrl+S for "save as" dialog + if ('S' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15)) + { + showSaveDialog(window); + return false; + } + TranslateMessage(&message); if ((message.wParam >= VK_F1 && message.wParam <= VK_F24) || message.wParam == VK_HOME || message.wParam == VK_END || @@ -2113,13 +2250,7 @@ static bool handleMessage(MSG& message, int& keyCode) return true; } - // Intercept Ctrl+C for copy to clipboard - if ('C' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15)) - ::SendMessage(message.hwnd, WM_COPY, 0, 0); - - // Intercept Ctrl+S for "save as" dialog - if ('S' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15)) - showSaveDialog(window); + // fallthru default: DispatchMessage(&message); @@ -2140,7 +2271,7 @@ static bool handleMessage(MSG& message, int& keyCode) /* * process until queue is empty but don't wait. */ -int cv::pollKey() +int pollKey_W32() { CV_TRACE_FUNCTION(); for(;;) @@ -2156,7 +2287,7 @@ int cv::pollKey() } CV_IMPL int -cvWaitKey( int delay ) +cvWaitKey(int delay) { int64 time0 = cv::getTickCount(); int64 timeEnd = time0 + (int64)(delay * 0.001f * cv::getTickFrequency()); @@ -2165,9 +2296,9 @@ cvWaitKey( int delay ) { MSG message; - if( (delay <= 0) && hg_windows) + if ((delay <= 0) && !getWindowsList().empty()) GetMessage(&message, 0, 0, 0); - else if( PeekMessage(&message, 0, 0, 0, PM_REMOVE) == FALSE ) + else if (PeekMessage(&message, 0, 0, 0, PM_REMOVE) == FALSE) { int64 t = cv::getTickCount(); if (t - timeEnd >= 0) @@ -2183,110 +2314,135 @@ cvWaitKey( int delay ) } -static CvTrackbar* -icvFindTrackbarByName( const CvWindow* window, const char* name ) +static +std::shared_ptr icvFindTrackbarByName(CvWindow& window, const std::string& name) { - CvTrackbar* trackbar = window->toolbar.first; - - for( ; trackbar != 0 && strcmp( trackbar->name, name ) != 0; trackbar = trackbar->next ) - ; - - return trackbar; + auto trackbars = window.toolbar.trackbars; + for (auto it = trackbars.begin(); it != trackbars.end(); ++it) + { + auto& trackbar = *it; + CV_Assert(trackbar); + if (trackbar->name == name) + return trackbar; + } + return std::shared_ptr(); +} +static inline +std::shared_ptr icvFindTrackbarByName(const std::shared_ptr& window, const std::string& name) +{ + CV_Assert(window); + return icvFindTrackbarByName(window, name); } +static +std::shared_ptr createTrackbar_(CvWindow& window, const std::string& trackbar_name, + int count, + TrackbarCallback onChange, void* userdata); static int -icvCreateTrackbar( const char* trackbar_name, const char* window_name, - int* val, int count, CvTrackbarCallback on_notify, - CvTrackbarCallback2 on_notify2, void* userdata ) +icvCreateTrackbar(const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback on_notify, + CvTrackbarCallback2 on_notify2, void* userdata) { - int result = 0; + CV_FUNCNAME("icvCreateTrackbar"); - CV_FUNCNAME( "icvCreateTrackbar" ); + AutoLock lock(getWindowMutex()); - __BEGIN__; + if (!window_name || !trackbar_name) + CV_Error(Error::StsNullPtr, "NULL window or trackbar name"); - char slider_name[32]; - CvWindow* window = 0; - CvTrackbar* trackbar = 0; - int pos = 0; + if (count < 0) + CV_Error(Error::StsOutOfRange, "Bad trackbar maximal value"); - if( !window_name || !trackbar_name ) - CV_ERROR( CV_StsNullPtr, "NULL window or trackbar name" ); + auto window = icvFindWindowByName(window_name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name)); - if( count < 0 ) - CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + auto trackbar = icvFindTrackbarByName(*window, trackbar_name); + if (!trackbar) + trackbar = createTrackbar_(*window, trackbar_name, count, nullptr, userdata); + CV_Assert(trackbar); - window = icvFindWindowByName(window_name); - if( !window ) - EXIT; + trackbar->notify = on_notify; + trackbar->notify2 = on_notify2; + trackbar->userdata = userdata; + trackbar->data = val; - trackbar = icvFindTrackbarByName(window,trackbar_name); - if( !trackbar ) - { - TBBUTTON tbs = {}; - TBBUTTONINFO tbis = {}; - RECT rect = { 0 }; - int bcount; - int len = (int)strlen( trackbar_name ); + return 1; +} - // create toolbar if it is not created yet - if( !window->toolbar.toolbar ) - { - const int default_height = 30; - - // CreateToolbarEx is deprecated and forces linking against Comctl32.lib. - window->toolbar.toolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, - WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE | BTNS_AUTOSIZE | BTNS_BUTTON, - 0, 0, 0, 0, - window->frame, NULL, GetModuleHandle(NULL), NULL); - // CreateToolbarEx automatically sends this but CreateWindowEx doesn't. - SendMessage(window->toolbar.toolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); - - GetClientRect(window->frame, &rect); - MoveWindow( window->toolbar.toolbar, 0, 0, - rect.right - rect.left, default_height, TRUE); - SendMessage(window->toolbar.toolbar, TB_AUTOSIZE, 0, 0); - ShowWindow(window->toolbar.toolbar, SW_SHOW); - - window->toolbar.first = 0; - window->toolbar.pos = 0; - window->toolbar.rows = 0; - window->toolbar.toolBarProc = - (WNDPROC)icvGetWindowLongPtr(window->toolbar.toolbar, CV_WNDPROC); - - icvUpdateWindowPos(window); - - // Subclassing from toolbar - icvSetWindowLongPtr(window->toolbar.toolbar, CV_WNDPROC, HGToolbarProc); - icvSetWindowLongPtr(window->toolbar.toolbar, CV_USERDATA, window); - } +static void createToolbar_(CvWindow& window) +{ + CV_Assert(!window.toolbar.toolbar); + + const int default_height = 30; + + // CreateToolbarEx is deprecated and forces linking against Comctl32.lib. + window.toolbar.toolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, + WS_CHILD | CCS_TOP | TBSTYLE_WRAPABLE | BTNS_AUTOSIZE | BTNS_BUTTON, + 0, 0, 0, 0, + window.frame, NULL, GetModuleHandle(NULL), NULL); + // CreateToolbarEx automatically sends this but CreateWindowEx doesn't. + SendMessage(window.toolbar.toolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + + RECT rect; + GetClientRect(window.frame, &rect); + MoveWindow(window.toolbar.toolbar, 0, 0, + rect.right - rect.left, default_height, TRUE); + SendMessage(window.toolbar.toolbar, TB_AUTOSIZE, 0, 0); + ShowWindow(window.toolbar.toolbar, SW_SHOW); + + window.toolbar.pos = 0; + window.toolbar.rows = 0; + window.toolbar.toolBarProc = + (WNDPROC)icvGetWindowLongPtr(window.toolbar.toolbar, CV_WNDPROC); + + icvUpdateWindowPos(window); - /* Retrieve current buttons count */ - bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + // Subclassing from toolbar + icvSetWindowLongPtr(window.toolbar.toolbar, CV_WNDPROC, HGToolbarProc); + icvSetWindowLongPtr(window.toolbar.toolbar, CV_USERDATA, (void*)&window); - if(bcount > 1) - { - /* If this is not the first button then we need to - separate it from the previous one */ - tbs.iBitmap = 0; - tbs.idCommand = bcount; // Set button id to it's number - tbs.iString = 0; - tbs.fsStyle = TBSTYLE_SEP; - tbs.fsState = TBSTATE_ENABLED; - SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); - - // Retrieve current buttons count - bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); - } +} + +static +std::shared_ptr createTrackbar_(CvWindow& window, const std::string& trackbar_name, + int count, + TrackbarCallback onChange, void* userdata) +{ + // create toolbar if it is not created yet + if (!window.toolbar.toolbar) + { + createToolbar_(window); + } - /* Add a button which we're going to cover with the slider */ + TBBUTTON tbs = {}; + + /* Retrieve current buttons count */ + int bcount = (int)SendMessage(window.toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + + if (bcount > 1) + { + /* If this is not the first button then we need to + separate it from the previous one */ tbs.iBitmap = 0; tbs.idCommand = bcount; // Set button id to it's number + tbs.iString = 0; + tbs.fsStyle = TBSTYLE_SEP; tbs.fsState = TBSTATE_ENABLED; + SendMessage(window.toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); + + // Retrieve current buttons count + bcount = (int)SendMessage(window.toolbar.toolbar, TB_BUTTONCOUNT, 0, 0); + } + + /* Add a button which we're going to cover with the slider */ + tbs.iBitmap = 0; + tbs.idCommand = bcount; // Set button id to it's number + tbs.fsState = TBSTATE_ENABLED; #if 0/*!defined WIN64 && !defined EM64T*/ - tbs.fsStyle = 0; - tbs.iString = 0; + tbs.fsStyle = 0; + tbs.iString = 0; #else #ifndef TBSTYLE_AUTOSIZE @@ -2296,320 +2452,640 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name, #ifndef TBSTYLE_GROUP #define TBSTYLE_GROUP 0x0004 #endif - //tbs.fsStyle = TBSTYLE_AUTOSIZE; - tbs.fsStyle = TBSTYLE_GROUP; - tbs.iString = (INT_PTR)trackbar_text; + //tbs.fsStyle = TBSTYLE_AUTOSIZE; + tbs.fsStyle = TBSTYLE_GROUP; + tbs.iString = (INT_PTR)trackbar_text; #endif - SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); - - /* Adjust button size to the slider */ - tbis.cbSize = sizeof(tbis); - tbis.dwMask = TBIF_SIZE; - - GetClientRect(window->hwnd, &rect); - tbis.cx = (unsigned short)(rect.right - rect.left); - - SendMessage(window->toolbar.toolbar, TB_SETBUTTONINFO, - (WPARAM)tbs.idCommand, (LPARAM)&tbis); - - /* Get button pos */ - SendMessage(window->toolbar.toolbar, TB_GETITEMRECT, - (WPARAM)tbs.idCommand, (LPARAM)&rect); - - /* Create a slider */ - trackbar = (CvTrackbar*)cvAlloc( sizeof(CvTrackbar) + len + 1 ); - trackbar->signature = CV_TRACKBAR_MAGIC_VAL; - trackbar->notify = 0; - trackbar->notify2 = 0; - trackbar->parent = window; - trackbar->pos = 0; - trackbar->data = 0; - trackbar->id = bcount; - trackbar->next = window->toolbar.first; - trackbar->name = (char*)(trackbar + 1); - memcpy( trackbar->name, trackbar_name, len + 1 ); - window->toolbar.first = trackbar; - - sprintf(slider_name, "Trackbar%p", val); - trackbar->hwnd = CreateWindowEx(0, TRACKBAR_CLASS, slider_name, - WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS | - TBS_FIXEDLENGTH | TBS_HORZ | TBS_BOTTOM, - rect.left + HG_BUDDY_WIDTH, rect.top, - rect.right - rect.left - HG_BUDDY_WIDTH, - rect.bottom - rect.top, window->toolbar.toolbar, - (HMENU)(size_t)bcount, hg_hinstance, 0); - - sprintf(slider_name,"Buddy%p", val); - trackbar->buddy = CreateWindowEx(0, "STATIC", slider_name, - WS_CHILD | SS_RIGHT, - rect.left, rect.top, - HG_BUDDY_WIDTH, rect.bottom - rect.top, - window->toolbar.toolbar, 0, hg_hinstance, 0); - - icvSetWindowLongPtr( trackbar->hwnd, CV_USERDATA, trackbar ); - - /* Minimize the number of rows */ - SendMessage( window->toolbar.toolbar, TB_SETROWS, - MAKEWPARAM(1, FALSE), (LPARAM)&rect ); - } - else - { - trackbar->data = 0; - trackbar->notify = 0; - trackbar->notify2 = 0; - } + SendMessage(window.toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs); + + TBBUTTONINFO tbis = {}; + + /* Adjust button size to the slider */ + tbis.cbSize = sizeof(tbis); + tbis.dwMask = TBIF_SIZE; + + RECT rect = { 0 }; + GetClientRect(window.hwnd, &rect); + tbis.cx = (unsigned short)(rect.right - rect.left); + + SendMessage(window.toolbar.toolbar, TB_SETBUTTONINFO, + (WPARAM)tbs.idCommand, (LPARAM)&tbis); + + /* Get button pos */ + SendMessage(window.toolbar.toolbar, TB_GETITEMRECT, + (WPARAM)tbs.idCommand, (LPARAM)&rect); + + /* Create a slider */ + auto trackbar = std::make_shared(window, trackbar_name); + trackbar->id = bcount; + window.toolbar.trackbars.push_back(trackbar); + + auto slider_name = cv::format("Trackbar%p", trackbar.get()); + trackbar->hwnd = CreateWindowEx(0, TRACKBAR_CLASS, slider_name.c_str(), + WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS | + TBS_FIXEDLENGTH | TBS_HORZ | TBS_BOTTOM, + rect.left + HG_BUDDY_WIDTH, rect.top, + rect.right - rect.left - HG_BUDDY_WIDTH, + rect.bottom - rect.top, window.toolbar.toolbar, + (HMENU)(size_t)bcount, hg_hinstance, 0); + + slider_name = cv::format("Buddy%p", trackbar.get()); + trackbar->buddy = CreateWindowEx(0, "STATIC", slider_name.c_str(), + WS_CHILD | SS_RIGHT, + rect.left, rect.top, + HG_BUDDY_WIDTH, rect.bottom - rect.top, + window.toolbar.toolbar, 0, hg_hinstance, 0); + + icvSetWindowLongPtr(trackbar->hwnd, CV_USERDATA, (void*)trackbar.get()); + + /* Minimize the number of rows */ + SendMessage(window.toolbar.toolbar, TB_SETROWS, + MAKEWPARAM(1, FALSE), (LPARAM)&rect); trackbar->maxval = count; /* Adjust slider parameters */ SendMessage(trackbar->hwnd, TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)0); SendMessage(trackbar->hwnd, TBM_SETRANGEMAX, (WPARAM)TRUE, (LPARAM)count); - SendMessage(trackbar->hwnd, TBM_SETTICFREQ, (WPARAM)1, (LPARAM)0 ); - if( val ) - pos = *val; + SendMessage(trackbar->hwnd, TBM_SETTICFREQ, (WPARAM)1, (LPARAM)0); - SendMessage(trackbar->hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos ); - SendMessage(window->toolbar.toolbar, TB_AUTOSIZE, 0, 0); + int pos = 0; + SendMessage(trackbar->hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); + SendMessage(window.toolbar.toolbar, TB_AUTOSIZE, 0, 0); trackbar->pos = -1; - icvUpdateTrackbar( trackbar, pos ); - ShowWindow( trackbar->buddy, SW_SHOW ); - ShowWindow( trackbar->hwnd, SW_SHOW ); - - trackbar->notify = on_notify; - trackbar->notify2 = on_notify2; - trackbar->userdata = userdata; - trackbar->data = val; + icvUpdateTrackbar(*trackbar, pos); + ShowWindow(trackbar->buddy, SW_SHOW); + ShowWindow(trackbar->hwnd, SW_SHOW); /* Resize the window to reflect the toolbar resizing*/ icvUpdateWindowPos(window); - result = 1; - - __END__; + trackbar->onChangeCallback = onChange; + trackbar->userdata = userdata; - return result; + return trackbar; } CV_IMPL int -cvCreateTrackbar( const char* trackbar_name, const char* window_name, - int* val, int count, CvTrackbarCallback on_notify ) +cvCreateTrackbar(const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback on_notify) { - return icvCreateTrackbar( trackbar_name, window_name, val, count, - on_notify, 0, 0 ); + return icvCreateTrackbar(trackbar_name, window_name, val, count, + on_notify, 0, 0); } CV_IMPL int -cvCreateTrackbar2( const char* trackbar_name, const char* window_name, - int* val, int count, CvTrackbarCallback2 on_notify2, - void* userdata ) +cvCreateTrackbar2(const char* trackbar_name, const char* window_name, + int* val, int count, CvTrackbarCallback2 on_notify2, + void* userdata) { - return icvCreateTrackbar( trackbar_name, window_name, val, count, - 0, on_notify2, userdata ); + return icvCreateTrackbar(trackbar_name, window_name, val, count, + 0, on_notify2, userdata); } CV_IMPL void -cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param ) +cvSetMouseCallback(const char* name, CvMouseCallback on_mouse, void* param) { - CV_FUNCNAME( "cvSetMouseCallback" ); - - __BEGIN__; + CV_FUNCNAME("cvSetMouseCallback"); - CvWindow* window = 0; + if (!name) + CV_Error(Error::StsNullPtr, "NULL window name"); - if( !window_name ) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); + AutoLock lock(getWindowMutex()); - window = icvFindWindowByName(window_name); - if( !window ) - EXIT; + auto window = icvFindWindowByName(name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", name)); window->on_mouse = on_mouse; window->on_mouse_param = param; - - __END__; } -CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) +CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name) { - int pos = -1; - - CV_FUNCNAME( "cvGetTrackbarPos" ); + CV_FUNCNAME("cvGetTrackbarPos"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - CvWindow* window; - CvTrackbar* trackbar = 0; + if (trackbar_name == 0 || window_name == 0) + CV_Error(Error::StsNullPtr, "NULL trackbar or window name"); - if( trackbar_name == 0 || window_name == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); - - window = icvFindWindowByName( window_name ); - if( window ) - trackbar = icvFindTrackbarByName( window, trackbar_name ); - - if( trackbar ) - pos = trackbar->pos; + auto window = icvFindWindowByName(window_name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name)); - __END__; + auto trackbar = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar) + CV_Error_(Error::StsNullPtr, ("NULL trackbar: '%s'", trackbar_name)); - return pos; + return trackbar->pos; } -CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ) +CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos) { - CV_FUNCNAME( "cvSetTrackbarPos" ); + CV_FUNCNAME("cvSetTrackbarPos"); - __BEGIN__; + AutoLock lock(getWindowMutex()); - CvWindow* window; - CvTrackbar* trackbar = 0; + if (trackbar_name == 0 || window_name == 0) + CV_Error(Error::StsNullPtr, "NULL trackbar or window name"); - if( trackbar_name == 0 || window_name == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + auto window = icvFindWindowByName(window_name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name)); - window = icvFindWindowByName( window_name ); - if( window ) - trackbar = icvFindTrackbarByName( window, trackbar_name ); + auto trackbar = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar) + CV_Error_(Error::StsNullPtr, ("NULL trackbar: '%s'", trackbar_name)); - if( trackbar ) { - if( pos < 0 ) + if (pos < 0) pos = 0; - if( pos > trackbar->maxval ) + if (pos > trackbar->maxval) pos = trackbar->maxval; - SendMessage( trackbar->hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos ); - icvUpdateTrackbar( trackbar, pos ); + SendMessage(trackbar->hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); + icvUpdateTrackbar(*trackbar, pos); } - - __END__; } CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval) { - CV_FUNCNAME( "cvSetTrackbarMax" ); + CV_FUNCNAME("cvSetTrackbarMax"); + + if (trackbar_name == 0 || window_name == 0) + { + CV_Error(Error::StsNullPtr, "NULL trackbar or window name"); + } - __BEGIN__; + AutoLock lock(getWindowMutex()); + auto window = icvFindWindowByName(window_name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name)); + + auto trackbar = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar) + CV_Error_(Error::StsNullPtr, ("NULL trackbar: '%s'", trackbar_name)); + + // FIXIT if (maxval >= 0) { - CvWindow* window = 0; - CvTrackbar* trackbar = 0; - if (trackbar_name == 0 || window_name == 0) + // The position will be min(pos, maxval). + trackbar->maxval = (trackbar->minval>maxval)?trackbar->minval:maxval; + SendMessage(trackbar->hwnd, TBM_SETRANGEMAX, (WPARAM)TRUE, (LPARAM)maxval); + } +} + + +CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval) +{ + CV_FUNCNAME("cvSetTrackbarMin"); + + if (trackbar_name == 0 || window_name == 0) + { + CV_Error(Error::StsNullPtr, "NULL trackbar or window name"); + } + + AutoLock lock(getWindowMutex()); + + auto window = icvFindWindowByName(window_name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name)); + + auto trackbar = icvFindTrackbarByName(window, trackbar_name); + if (!trackbar) + CV_Error_(Error::StsNullPtr, ("NULL trackbar: '%s'", trackbar_name)); + + // FIXIT + if (minval >= 0) + { + // The position will be min(pos, maxval). + trackbar->minval = (minvalmaxval)?minval:trackbar->maxval; + SendMessage(trackbar->hwnd, TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)minval); + } +} + + +CV_IMPL void* cvGetWindowHandle(const char* window_name) +{ + CV_FUNCNAME("cvGetWindowHandle"); + + AutoLock lock(getWindowMutex()); + + if (window_name == 0) + CV_Error(Error::StsNullPtr, "NULL window name"); + + auto window = icvFindWindowByName(window_name); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%s'", window_name)); + + return (void*)window->hwnd; +} + +// FIXIT: result is not safe to use +CV_IMPL const char* cvGetWindowName(void* window_handle) +{ + CV_FUNCNAME("cvGetWindowName"); + + AutoLock lock(getWindowMutex()); + + if (window_handle == 0) + CV_Error(Error::StsNullPtr, "NULL window handle"); + + auto window = icvWindowByHWND((HWND)window_handle); + if (!window) + CV_Error_(Error::StsNullPtr, ("NULL window: '%p'", window_handle)); + + return window->name.c_str(); +} + + +CV_IMPL void +cvSetPreprocessFuncWin32_(const void* callback) +{ + hg_on_preprocess = (CvWin32WindowCallback)callback; +} + +CV_IMPL void +cvSetPostprocessFuncWin32_(const void* callback) +{ + hg_on_postprocess = (CvWin32WindowCallback)callback; +} + + + +namespace cv { namespace impl { + +using namespace cv::highgui_backend; + +class Win32UITrackbar; + +class Win32UIWindow + : public UIWindow + , public std::enable_shared_from_this +{ +protected: + const std::string name_; + std::weak_ptr window_; + std::map > trackbars_; +public: + Win32UIWindow(const std::string& name, const std::shared_ptr& window) + : name_(name) + , window_(window) + { + // nothing + } + + ~Win32UIWindow() CV_OVERRIDE + { + if (!window_.expired()) + destroy(); + CV_LOG_DEBUG(NULL, "OpenCV/UI/Win32UI: Win32UIWindow(" << name_ << ") is disposed"); + } + + const std::string& getID() const CV_OVERRIDE { return name_; } + + bool isActive() const CV_OVERRIDE { return !window_.expired(); } + + void destroy() CV_OVERRIDE + { + cv::AutoLock lock(getWindowMutex()); + if (!window_.expired()) { - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + auto window = window_.lock(); + if (window) + window->destroy(); + window_.reset(); } + } + + void imshow(InputArray image) CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + Mat image_mat = image.getMat(); + showImage_(window, image_mat); + } - window = icvFindWindowByName(window_name); - if (window) + double getProperty(int prop) const CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + // see cvGetWindowProperty + switch ((WindowPropertyFlags)prop) { - trackbar = icvFindTrackbarByName(window, trackbar_name); - if (trackbar) - { - // The position will be min(pos, maxval). - trackbar->maxval = (trackbar->minval>maxval)?trackbar->minval:maxval; - SendMessage(trackbar->hwnd, TBM_SETRANGEMAX, (WPARAM)TRUE, (LPARAM)maxval); - } + case WND_PROP_FULLSCREEN: + return (double)window.status; + + case WND_PROP_AUTOSIZE: + return (window.flags & WINDOW_AUTOSIZE) ? 1.0 : 0.0; + + case WND_PROP_ASPECT_RATIO: + return static_cast(window.width) / window.height; + +#ifdef HAVE_OPENGL + case WND_PROP_OPENGL: + return window.useGl ? 1.0 : 0.0; +#endif + + case WND_PROP_VISIBLE: + return 1.0; + + case WND_PROP_TOPMOST: + return getPropTopmost_(window); + + case WND_PROP_VSYNC: + return getPropVsync_(window); + + // don't use default, add unsupported cases below: + // case WND_PROP_UNSUPPORTED: // fallthru + // break; } + return std::numeric_limits::quiet_NaN(); } - __END__; -} + bool setProperty(int prop, double value) CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + // see cvSetWindowProperty + switch ((WindowPropertyFlags)prop) + { + case WND_PROP_FULLSCREEN: + if (value != WINDOW_NORMAL && value != WINDOW_FULLSCREEN) // bad arg + break; + setModeWindow_(window, (int)value); + return true; + case WND_PROP_TOPMOST: + return setPropTopmost_(window, value != 0.0); -CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval) -{ - CV_FUNCNAME( "cvSetTrackbarMin" ); + case WND_PROP_VSYNC: + return setPropVsync_(window, value != 0.0); - __BEGIN__; + // don't use default, add unsupported cases below: + // case WND_PROP_UNSUPPORTED: // fallthru + case WND_PROP_AUTOSIZE: // fallthru + case WND_PROP_ASPECT_RATIO: // fallthru + case WND_PROP_OPENGL: // fallthru + case WND_PROP_VISIBLE: // fallthru + break; + } + return false; + } - if (minval >= 0) + void resize(int width, int height) CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + resizeWindow_(window, Size(width, height)); + } + + void move(int x, int y) CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + moveWindow_(window, Point(x, y)); + } + + Rect getImageRect() const CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + return getImageRect_(window); + } + + void setTitle(const std::string& title) CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + if (!SetWindowText(window.frame, title.c_str())) + CV_Error_(Error::StsError, ("Failed to set \"%s\" window title to \"%s\"", window.name.c_str(), title.c_str())); + } + + void setMouseCallback(MouseCallback onMouse, void* userdata /*= 0*/) CV_OVERRIDE { - CvWindow* window = 0; - CvTrackbar* trackbar = 0; - if (trackbar_name == 0 || window_name == 0) + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + window.on_mouse = onMouse; + window.on_mouse_param = userdata; + } + + std::shared_ptr createTrackbar( + const std::string& name, + int count, + TrackbarCallback onChange /*= 0*/, + void* userdata /*= 0*/ + ) CV_OVERRIDE + { + auto window_ptr = window_.lock(); + CV_Assert(window_ptr); + CvWindow& window = *window_ptr; + CV_LOG_INFO(NULL, "OpenCV/UI: Creating Win32UI trackbar at '" << name_ << "': '" << name << "'"); + auto trackbar = createTrackbar_(window, name, count, onChange, userdata); + auto ui_trackbar = std::make_shared(name, trackbar, shared_from_this()); { - CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name"); + cv::AutoLock lock(getWindowMutex()); + trackbars_.emplace(name, ui_trackbar); } + return std::static_pointer_cast(ui_trackbar); + } - window = icvFindWindowByName(window_name); - if (window) + std::shared_ptr findTrackbar(const std::string& name) CV_OVERRIDE + { + cv::AutoLock lock(getWindowMutex()); + auto i = trackbars_.find(name); + if (i != trackbars_.end()) { - trackbar = icvFindTrackbarByName(window, trackbar_name); - if (trackbar) - { - // The position will be min(pos, maxval). - trackbar->minval = (minvalmaxval)?minval:trackbar->maxval; - SendMessage(trackbar->hwnd, TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)minval); - } + return std::static_pointer_cast(i->second); } + return std::shared_ptr(); } - - __END__; -} +}; // Win32UIWindow -CV_IMPL void* cvGetWindowHandle( const char* window_name ) +class Win32UITrackbar : public UITrackbar { - void* hwnd = 0; +protected: + /*const*/ std::string name_; + std::weak_ptr trackbar_; + std::weak_ptr parent_; + std::map > trackbars_; +public: + Win32UITrackbar(const std::string& name, const std::shared_ptr& trackbar, const std::shared_ptr& parent) + : trackbar_(trackbar) + , parent_(parent) + { + name_ = std::string("<") + name + ">@" + parent->getID(); + } - CV_FUNCNAME( "cvGetWindowHandle" ); + ~Win32UITrackbar() CV_OVERRIDE + { + if (!trackbar_.expired()) + destroy(); + CV_LOG_DEBUG(NULL, "OpenCV/UI/Win32UI: Win32UITrackbar(" << name_ << ") is disposed"); + } - __BEGIN__; + const std::string& getID() const CV_OVERRIDE { return name_; } - CvWindow* window; + bool isActive() const CV_OVERRIDE { return !trackbar_.expired(); } - if( window_name == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL window name" ); + void destroy() CV_OVERRIDE + { + // nothing (destroyed with parent window, dedicated trackbar removal is not supported) + } - window = icvFindWindowByName( window_name ); - if( window ) - hwnd = (void*)window->hwnd; + int getPos() const CV_OVERRIDE + { + auto trackbar_ptr = trackbar_.lock(); + CV_Assert(trackbar_ptr); + CvTrackbar& trackbar = *trackbar_ptr; + return trackbar.pos; + } + void setPos(int pos) CV_OVERRIDE + { + auto trackbar_ptr = trackbar_.lock(); + CV_Assert(trackbar_ptr); + CvTrackbar& trackbar = *trackbar_ptr; + SendMessage(trackbar.hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); + icvUpdateTrackbar(trackbar, pos); + } - __END__; + cv::Range getRange() const CV_OVERRIDE + { + auto trackbar_ptr = trackbar_.lock(); + CV_Assert(trackbar_ptr); + CvTrackbar& trackbar = *trackbar_ptr; + return cv::Range(trackbar.minval, trackbar.maxval); + } - return hwnd; -} + void setRange(const cv::Range& range) CV_OVERRIDE + { + auto trackbar_ptr = trackbar_.lock(); + CV_Assert(trackbar_ptr); + CvTrackbar& trackbar = *trackbar_ptr; + CV_CheckLE(range.start, range.end, "Invalid trackbar range"); + trackbar.minval = range.start; + trackbar.maxval = range.start; + SendMessage(trackbar.hwnd, TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)trackbar.minval); + SendMessage(trackbar.hwnd, TBM_SETRANGEMAX, (WPARAM)TRUE, (LPARAM)trackbar.maxval); + } +}; // Win32UITrackbar -CV_IMPL const char* cvGetWindowName( void* window_handle ) +class Win32BackendUI : public UIBackend { - const char* window_name = ""; +public: + ~Win32BackendUI() CV_OVERRIDE + { + destroyAllWindows(); + } - CV_FUNCNAME( "cvGetWindowName" ); + void destroyAllWindows() CV_OVERRIDE + { + cvDestroyAllWindows(); + } - __BEGIN__; + // namedWindow + virtual std::shared_ptr createWindow( + const std::string& winname, + int flags + ) CV_OVERRIDE + { + CV_LOG_INFO(NULL, "OpenCV/UI: Creating Win32UI window: " << winname << " (" << flags << ")"); + auto window = namedWindow_(winname, flags); + auto ui_window = std::make_shared(winname, window); + return ui_window; + } - CvWindow* window; + int waitKeyEx(int delay) CV_OVERRIDE + { + return cvWaitKey(delay); + } + int pollKey() CV_OVERRIDE + { + return pollKey_W32(); + } +}; // Win32BackendUI - if( window_handle == 0 ) - CV_ERROR( CV_StsNullPtr, "NULL window" ); +static +std::shared_ptr& getInstance() +{ + static std::shared_ptr g_instance = std::make_shared(); + return g_instance; +} - window = icvWindowByHWND( (HWND)window_handle ); - if( window ) - window_name = window->name; +} // namespace impl - __END__; +#ifndef BUILD_PLUGIN +namespace highgui_backend { - return window_name; +std::shared_ptr createUIBackendWin32UI() +{ + return impl::getInstance(); } +} // namespace highgui_backend +#endif -CV_IMPL void -cvSetPreprocessFuncWin32_(const void* callback) +} // namespace + + +#ifdef BUILD_PLUGIN + +#define ABI_VERSION 0 +#define API_VERSION 0 +#include "plugin_api.hpp" + +static +CvResult cv_getInstance(CV_OUT CvPluginUIBackend* handle) CV_NOEXCEPT { - hg_on_preprocess = (CvWin32WindowCallback)callback; + try + { + if (!handle) + return CV_ERROR_FAIL; + *handle = cv::impl::getInstance().get(); + return CV_ERROR_OK; + } + catch (...) + { + return CV_ERROR_FAIL; + } } -CV_IMPL void -cvSetPostprocessFuncWin32_(const void* callback) +static const OpenCV_UI_Plugin_API plugin_api = { - hg_on_postprocess = (CvWin32WindowCallback)callback; + { + sizeof(OpenCV_UI_Plugin_API), ABI_VERSION, API_VERSION, + CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS, + "Win32 OpenCV UI plugin" + }, + { + /* 1*/cv_getInstance + } +}; + +const OpenCV_UI_Plugin_API* CV_API_CALL opencv_ui_plugin_init_v0(int requested_abi_version, int requested_api_version, void* /*reserved=NULL*/) CV_NOEXCEPT +{ + if (requested_abi_version == ABI_VERSION && requested_api_version <= API_VERSION) + return &plugin_api; + return NULL; } -#endif //_WIN32 +#endif // BUILD_PLUGIN + +#endif // HAVE_WIN32UI diff --git a/modules/highgui/src/window_winrt_bridge.cpp b/modules/highgui/src/window_winrt_bridge.cpp index 13edbe5b83d2..6057f2d5b4ba 100644 --- a/modules/highgui/src/window_winrt_bridge.cpp +++ b/modules/highgui/src/window_winrt_bridge.cpp @@ -271,7 +271,7 @@ void CvWindow::createSlider(cv::String name, int* val, int count, CvTrackbarCall // Image control is loaded. See callback implementation in CvWindow ctor. slider->Width = sliderDefaultWidth; } - slider->Value = *val; + slider->Value = val ? *val : 0; slider->Maximum = count; slider->Visibility = Windows::UI::Xaml::Visibility::Visible; slider->Margin = Windows::UI::Xaml::ThicknessHelper::FromLengths(10, 10, 10, 0); diff --git a/modules/highgui/test/test_gui.cpp b/modules/highgui/test/test_gui.cpp index c973771e987b..6bf634b5001d 100644 --- a/modules/highgui/test/test_gui.cpp +++ b/modules/highgui/test/test_gui.cpp @@ -47,13 +47,18 @@ namespace opencv_test { namespace { inline void verify_size(const std::string &nm, const cv::Mat &img) { EXPECT_NO_THROW(imshow(nm, img)); - EXPECT_EQ(-1, waitKey(500)); + EXPECT_EQ(-1, waitKey(200)); Rect rc; EXPECT_NO_THROW(rc = getWindowImageRect(nm)); EXPECT_EQ(rc.size(), img.size()); } -#if !defined HAVE_GTK && !defined HAVE_QT && !defined HAVE_WIN32UI && !defined HAVE_COCOA +#if (!defined(ENABLE_PLUGINS) \ + && !defined HAVE_GTK \ + && !defined HAVE_QT \ + && !defined HAVE_WIN32UI \ + && !defined HAVE_COCOA \ + ) TEST(Highgui_GUI, DISABLED_regression) #else TEST(Highgui_GUI, regression) @@ -126,11 +131,15 @@ static void Foo(int, void* counter) } } -#if !defined HAVE_GTK && !defined HAVE_QT && !defined HAVE_WIN32UI -// && !defined HAVE_COCOA - TODO: fails on Mac? -TEST(Highgui_GUI, DISABLED_trackbar) +#if (!defined(ENABLE_PLUGINS) \ + && !defined HAVE_GTK \ + && !defined HAVE_QT \ + && !defined HAVE_WIN32UI \ + ) \ + || defined(__APPLE__) // test fails on Mac (cocoa) +TEST(Highgui_GUI, DISABLED_trackbar_unsafe) #else -TEST(Highgui_GUI, trackbar) +TEST(Highgui_GUI, trackbar_unsafe) #endif { int value = 50; @@ -142,9 +151,52 @@ TEST(Highgui_GUI, trackbar) ASSERT_NO_THROW(namedWindow(window_name)); EXPECT_EQ((int)1, createTrackbar(trackbar_name, window_name, &value, 100, Foo, &callback_count)); EXPECT_EQ(value, getTrackbarPos(trackbar_name, window_name)); - EXPECT_EQ(0, callback_count); + EXPECT_GE(callback_count, 0); + EXPECT_LE(callback_count, 1); + int callback_count_base = callback_count; + EXPECT_NO_THROW(setTrackbarPos(trackbar_name, window_name, 90)); + EXPECT_EQ(callback_count_base + 1, callback_count); + EXPECT_EQ(90, value); + EXPECT_EQ(90, getTrackbarPos(trackbar_name, window_name)); + EXPECT_NO_THROW(destroyAllWindows()); +} + +static +void testTrackbarCallback(int pos, void* param) +{ + CV_Assert(param); + int* status = (int*)param; + status[0] = pos; + status[1]++; +} + +#if (!defined(ENABLE_PLUGINS) \ + && !defined HAVE_GTK \ + && !defined HAVE_QT \ + && !defined HAVE_WIN32UI \ + ) \ + || defined(__APPLE__) // test fails on Mac (cocoa) +TEST(Highgui_GUI, DISABLED_trackbar) +#else +TEST(Highgui_GUI, trackbar) +#endif +{ + int status[2] = {-1, 0}; // pos, counter + const std::string window_name("trackbar_test_window"); + const std::string trackbar_name("trackbar"); + + EXPECT_NO_THROW(destroyAllWindows()); + ASSERT_NO_THROW(namedWindow(window_name)); + EXPECT_EQ((int)1, createTrackbar(trackbar_name, window_name, NULL, 100, testTrackbarCallback, status)); + EXPECT_EQ(0, getTrackbarPos(trackbar_name, window_name)); + int callback_count = status[1]; + EXPECT_GE(callback_count, 0); + EXPECT_LE(callback_count, 1); + int callback_count_base = callback_count; EXPECT_NO_THROW(setTrackbarPos(trackbar_name, window_name, 90)); - EXPECT_EQ(1, callback_count); + callback_count = status[1]; + EXPECT_EQ(callback_count_base + 1, callback_count); + int value = status[0]; EXPECT_EQ(90, value); EXPECT_EQ(90, getTrackbarPos(trackbar_name, window_name)); EXPECT_NO_THROW(destroyAllWindows()); diff --git a/modules/imgcodecs/src/grfmt_exr.cpp b/modules/imgcodecs/src/grfmt_exr.cpp index 7acaf434c682..f3368587f338 100644 --- a/modules/imgcodecs/src/grfmt_exr.cpp +++ b/modules/imgcodecs/src/grfmt_exr.cpp @@ -158,6 +158,10 @@ bool ExrDecoder::readHeader() else { m_green = channels.findChannel( "Y" ); + if( !m_green ) + { + m_green = channels.findChannel( "Z" ); // Distance of the front of a sample from the viewer + } if( m_green ) { m_ischroma = true; diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index e1b8952ffe9d..88c960747c60 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -2926,6 +2926,22 @@ An example is shown below: */ CV_EXPORTS_W void createHanningWindow(OutputArray dst, Size winSize, int type); +/** @brief Performs the per-element division of the first Fourier spectrum by the second Fourier spectrum. + +The function cv::divSpectrums performs the per-element division of the first array by the second array. +The arrays are CCS-packed or complex matrices that are results of a real or complex Fourier transform. + +@param a first input array. +@param b second input array of the same size and type as src1 . +@param c output array of the same size and type as src1 . +@param flags operation flags; currently, the only supported flag is cv::DFT_ROWS, which indicates that +each row of src1 and src2 is an independent 1D Fourier spectrum. If you do not want to use this flag, then simply add a `0` as value. +@param conjB optional flag that conjugates the second input array before the multiplication (true) +or not (false). +*/ +CV_EXPORTS_W void divSpectrums(InputArray a, InputArray b, OutputArray c, + int flags, bool conjB = false); + //! @} imgproc_motion //! @addtogroup imgproc_misc diff --git a/modules/imgproc/src/color_lab.cpp b/modules/imgproc/src/color_lab.cpp index 337d601f697c..a181880862f1 100644 --- a/modules/imgproc/src/color_lab.cpp +++ b/modules/imgproc/src/color_lab.cpp @@ -1536,6 +1536,8 @@ static inline void trilinearPackedInterpolate(const v_uint16& inX, const v_uint1 #endif // CV_SIMD + + struct RGB2Lab_b { typedef uchar channel_type; @@ -1571,6 +1573,69 @@ struct RGB2Lab_b } } +#if CV_NEON + template + inline void rgb2lab_batch(const ushort* tab, + const v_uint8 vRi, const v_uint8 vGi, const v_uint8 vBi, + v_int32& vL, v_int32& va, v_int32& vb) const + { + // Define some scalar constants which we will make use of later + const int Lscale = (116*255+50)/100; + const int Lshift = -((16*255*(1 << lab_shift2) + 50)/100); + const int xyzDescaleShift = (1 << (lab_shift - 1)); + const int labDescaleShift = (1 << (lab_shift2 - 1)); + const int abShift = 128*(1 << lab_shift2); + + const int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], + C3 = coeffs[3], C4 = coeffs[4], C5 = coeffs[5], + C6 = coeffs[6], C7 = coeffs[7], C8 = coeffs[8]; + + // int R = tab[src[0]], G = tab[src[1]], B = tab[src[2]]; + v_int32 vR(tab[v_extract_n<4*n+0>(vRi)], tab[v_extract_n<4*n+1>(vRi)], + tab[v_extract_n<4*n+2>(vRi)], tab[v_extract_n<4*n+3>(vRi)]); + v_int32 vG(tab[v_extract_n<4*n+0>(vGi)], tab[v_extract_n<4*n+1>(vGi)], + tab[v_extract_n<4*n+2>(vGi)], tab[v_extract_n<4*n+3>(vGi)]); + v_int32 vB(tab[v_extract_n<4*n+0>(vBi)], tab[v_extract_n<4*n+1>(vBi)], + tab[v_extract_n<4*n+2>(vBi)], tab[v_extract_n<4*n+3>(vBi)]); + + /* int fX = LabCbrtTab_b[CV_DESCALE(R*C0 + G*C1 + B*C2, lab_shift)];*/ + v_int32 vfX = v_fma(vR, v_setall_s32(C0), v_setall_s32(xyzDescaleShift)); + vfX = v_fma(vG, v_setall_s32(C1), vfX); + vfX = v_fma(vB, v_setall_s32(C2), vfX); + vfX = v_shr(vfX); + vfX = v_int32(LabCbrtTab_b[v_extract_n<0>(vfX)], LabCbrtTab_b[v_extract_n<1>(vfX)], + LabCbrtTab_b[v_extract_n<2>(vfX)], LabCbrtTab_b[v_extract_n<3>(vfX)]); + + /* int fY = LabCbrtTab_b[CV_DESCALE(R*C3 + G*C4 + B*C5, lab_shift)]; */ + v_int32 vfY = v_fma(vR, v_setall_s32(C3), v_setall_s32(xyzDescaleShift)); + vfY = v_fma(vG, v_setall_s32(C4), vfY); + vfY = v_fma(vB, v_setall_s32(C5), vfY); + vfY = v_shr(vfY); + vfY = v_int32(LabCbrtTab_b[v_extract_n<0>(vfY)], LabCbrtTab_b[v_extract_n<1>(vfY)], + LabCbrtTab_b[v_extract_n<2>(vfY)], LabCbrtTab_b[v_extract_n<3>(vfY)]); + + /* int fZ = LabCbrtTab_b[CV_DESCALE(R*C6 + G*C7 + B*C8, lab_shift)];*/ + v_int32 vfZ = v_fma(vR, v_setall_s32(C6), v_setall_s32(xyzDescaleShift)); + vfZ = v_fma(vG, v_setall_s32(C7), vfZ); + vfZ = v_fma(vB, v_setall_s32(C8), vfZ); + vfZ = v_shr(vfZ); + vfZ = v_int32(LabCbrtTab_b[v_extract_n<0>(vfZ)], LabCbrtTab_b[v_extract_n<1>(vfZ)], + LabCbrtTab_b[v_extract_n<2>(vfZ)], LabCbrtTab_b[v_extract_n<3>(vfZ)]); + + /* int L = CV_DESCALE( Lscale*fY + Lshift, lab_shift2 );*/ + vL = v_fma(vfY, v_setall_s32(Lscale), v_setall_s32(Lshift+labDescaleShift)); + vL = v_shr(vL); + + /* int a = CV_DESCALE( 500*(fX - fY) + 128*(1 << lab_shift2), lab_shift2 );*/ + va = v_fma(vfX - vfY, v_setall_s32(500), v_setall_s32(abShift+labDescaleShift)); + va = v_shr(va); + + /* int b = CV_DESCALE( 200*(fY - fZ) + 128*(1 << lab_shift2), lab_shift2 );*/ + vb = v_fma(vfY - vfZ, v_setall_s32(200), v_setall_s32(abShift+labDescaleShift)); + vb = v_shr(vb); + } +#endif // CV_NEON + void operator()(const uchar* src, uchar* dst, int n) const { CV_INSTRUMENT_REGION(); @@ -1585,6 +1650,45 @@ struct RGB2Lab_b i = 0; +#if CV_NEON + // On each loop, we load nlanes of RGB/A v_uint8s and store nlanes of + // Lab v_uint8s + for(; i <= n - v_uint8::nlanes; i += v_uint8::nlanes, + src += scn*v_uint8::nlanes, dst += 3*v_uint8::nlanes ) + { + // Load 4 batches of 4 src + v_uint8 vRi, vGi, vBi; + if(scn == 4) + { + v_uint8 vAi; + v_load_deinterleave(src, vRi, vGi, vBi, vAi); + } + else // scn == 3 + { + v_load_deinterleave(src, vRi, vGi, vBi); + } + + // Do 4 batches of 4 RGB2Labs + v_int32 vL0, va0, vb0; + rgb2lab_batch<0>(tab, vRi, vGi, vBi, vL0, va0, vb0); + v_int32 vL1, va1, vb1; + rgb2lab_batch<1>(tab, vRi, vGi, vBi, vL1, va1, vb1); + v_int32 vL2, va2, vb2; + rgb2lab_batch<2>(tab, vRi, vGi, vBi, vL2, va2, vb2); + v_int32 vL3, va3, vb3; + rgb2lab_batch<3>(tab, vRi, vGi, vBi, vL3, va3, vb3); + + // Saturate, combine and store all batches + // dst[0] = saturate_cast(L); + // dst[1] = saturate_cast(a); + // dst[2] = saturate_cast(b); + v_store_interleave(dst, + v_pack(v_pack_u(vL0, vL1), v_pack_u(vL2, vL3)), + v_pack(v_pack_u(va0, va1), v_pack_u(va2, va3)), + v_pack(v_pack_u(vb0, vb1), v_pack_u(vb2, vb3))); + } +#endif // CV_NEON + #if CV_SIMD const int vsize = v_uint8::nlanes; const int xyzDescaleShift = 1 << (lab_shift - 1); diff --git a/modules/imgproc/src/intersection.cpp b/modules/imgproc/src/intersection.cpp index 3f749896a42c..47d3f3f457b5 100644 --- a/modules/imgproc/src/intersection.cpp +++ b/modules/imgproc/src/intersection.cpp @@ -47,24 +47,16 @@ namespace cv { -int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion ) +static int _rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, std::vector &intersection ) { CV_INSTRUMENT_REGION(); // L2 metric const float samePointEps = std::max(1e-16f, 1e-6f * (float)std::max(rect1.size.area(), rect2.size.area())); - if (rect1.size.empty() || rect2.size.empty()) - { - intersectingRegion.release(); - return INTERSECT_NONE; - } - Point2f vec1[4], vec2[4]; Point2f pts1[4], pts2[4]; - std::vector intersection; intersection.reserve(24); - rect1.points(pts1); rect2.points(pts2); @@ -92,8 +84,6 @@ int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& r intersection[i] = pts1[i]; } - Mat(intersection).copyTo(intersectingRegion); - return INTERSECT_FULL; } } @@ -300,7 +290,50 @@ int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& r } intersection.resize(N); - Mat(intersection).copyTo(intersectingRegion); + + return ret; +} + +int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion ) +{ + CV_INSTRUMENT_REGION(); + + if (rect1.size.empty() || rect2.size.empty()) + { + intersectingRegion.release(); + return INTERSECT_NONE; + } + + // Shift rectangles closer to origin (0, 0) to improve the calculation of the intesection region + // To do that, the average center of the rectangles is moved to the origin + const Point2f averageCenter = (rect1.center + rect2.center) / 2.0f; + + RotatedRect shiftedRect1(rect1); + RotatedRect shiftedRect2(rect2); + + // Move rectangles closer to origin + shiftedRect1.center -= averageCenter; + shiftedRect2.center -= averageCenter; + + std::vector intersection; intersection.reserve(24); + + const int ret = _rotatedRectangleIntersection(shiftedRect1, shiftedRect2, intersection); + + // If return is not None, the intersection Points are shifted back to the original position + // and copied to the interesectingRegion + if (ret != INTERSECT_NONE) + { + for (size_t i = 0; i < intersection.size(); ++i) + { + intersection[i] += averageCenter; + } + + Mat(intersection).copyTo(intersectingRegion); + } + else + { + intersectingRegion.release(); + } return ret; } diff --git a/modules/imgproc/src/phasecorr.cpp b/modules/imgproc/src/phasecorr.cpp index 4808f971ef14..9db436673ca5 100644 --- a/modules/imgproc/src/phasecorr.cpp +++ b/modules/imgproc/src/phasecorr.cpp @@ -82,9 +82,9 @@ static void magSpectrums( InputArray _src, OutputArray _dst) { if( k == 1 ) dataSrc += cols - 1, dataDst += cols - 1; - dataDst[0] = dataSrc[0]*dataSrc[0]; + dataDst[0] = (float)std::abs(dataSrc[0]); if( rows % 2 == 0 ) - dataDst[(rows-1)*stepDst] = dataSrc[(rows-1)*stepSrc]*dataSrc[(rows-1)*stepSrc]; + dataDst[(rows-1)*stepDst] = (float)std::abs(dataSrc[(rows-1)*stepSrc]); for( j = 1; j <= rows - 2; j += 2 ) { @@ -101,9 +101,9 @@ static void magSpectrums( InputArray _src, OutputArray _dst) { if( is_1d && cn == 1 ) { - dataDst[0] = dataSrc[0]*dataSrc[0]; + dataDst[0] = (float)std::abs(dataSrc[0]); if( cols % 2 == 0 ) - dataDst[j1] = dataSrc[j1]*dataSrc[j1]; + dataDst[j1] = (float)std::abs(dataSrc[j1]); } for( j = j0; j < j1; j += 2 ) @@ -126,9 +126,9 @@ static void magSpectrums( InputArray _src, OutputArray _dst) { if( k == 1 ) dataSrc += cols - 1, dataDst += cols - 1; - dataDst[0] = dataSrc[0]*dataSrc[0]; + dataDst[0] = std::abs(dataSrc[0]); if( rows % 2 == 0 ) - dataDst[(rows-1)*stepDst] = dataSrc[(rows-1)*stepSrc]*dataSrc[(rows-1)*stepSrc]; + dataDst[(rows-1)*stepDst] = std::abs(dataSrc[(rows-1)*stepSrc]); for( j = 1; j <= rows - 2; j += 2 ) { @@ -145,9 +145,9 @@ static void magSpectrums( InputArray _src, OutputArray _dst) { if( is_1d && cn == 1 ) { - dataDst[0] = dataSrc[0]*dataSrc[0]; + dataDst[0] = std::abs(dataSrc[0]); if( cols % 2 == 0 ) - dataDst[j1] = dataSrc[j1]*dataSrc[j1]; + dataDst[j1] = std::abs(dataSrc[j1]); } for( j = j0; j < j1; j += 2 ) @@ -158,7 +158,7 @@ static void magSpectrums( InputArray _src, OutputArray _dst) } } -static void divSpectrums( InputArray _srcA, InputArray _srcB, OutputArray _dst, int flags, bool conjB) +void divSpectrums( InputArray _srcA, InputArray _srcB, OutputArray _dst, int flags, bool conjB) { Mat srcA = _srcA.getMat(), srcB = _srcB.getMat(); int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type(); diff --git a/modules/imgproc/src/smooth.simd.hpp b/modules/imgproc/src/smooth.simd.hpp index 6c41b45e9ffc..3a39765c71f2 100644 --- a/modules/imgproc/src/smooth.simd.hpp +++ b/modules/imgproc/src/smooth.simd.hpp @@ -1236,8 +1236,12 @@ void hlineSmoothONa_yzy_a(const uint16_t* src, int cn, v_mul_expand(vx_load(src + pre_shift * cn), vx_setall_u16((uint16_t) *((uint32_t*)(m + pre_shift))), v_res0, v_res1); for (int j = 0; j < pre_shift; j ++) { + v_uint16 v_weight = vx_setall_u16((uint16_t) *((uint32_t*)(m + j))); v_uint32 v_add0, v_add1; - v_mul_expand(vx_load(src + j * cn) + vx_load(src + (n - 1 - j)*cn), vx_setall_u16((uint16_t) *((uint32_t*)(m + j))), v_add0, v_add1); + v_mul_expand(vx_load(src + j * cn), v_weight, v_add0, v_add1); + v_res0 += v_add0; + v_res1 += v_add1; + v_mul_expand(vx_load(src + (n - 1 - j)*cn), v_weight, v_add0, v_add1); v_res0 += v_add0; v_res1 += v_add1; } diff --git a/modules/imgproc/test/test_intersection.cpp b/modules/imgproc/test/test_intersection.cpp index 7527dd9a22cc..c455c439fce1 100644 --- a/modules/imgproc/test/test_intersection.cpp +++ b/modules/imgproc/test/test_intersection.cpp @@ -391,4 +391,21 @@ TEST(Imgproc_RotatedRectangleIntersection, regression_18520) } } +TEST(Imgproc_RotatedRectangleIntersection, regression_19824) +{ + RotatedRect r1( + Point2f(246805.033f, 4002326.94f), + Size2f(26.40587f, 6.20026f), + -62.10156f); + RotatedRect r2( + Point2f(246805.122f, 4002326.59f), + Size2f(27.4821f, 8.5361f), + -56.33761f); + + std::vector intersections; + int interType = cv::rotatedRectangleIntersection(r1, r2, intersections); + EXPECT_EQ(INTERSECT_PARTIAL, interType); + EXPECT_LE(intersections.size(), (size_t)7); +} + }} // namespace diff --git a/modules/imgproc/test/test_pc.cpp b/modules/imgproc/test/test_pc.cpp index 22c4bb5d7686..edfe0701e520 100644 --- a/modules/imgproc/test/test_pc.cpp +++ b/modules/imgproc/test/test_pc.cpp @@ -120,4 +120,278 @@ TEST(Imgproc_PhaseCorrelatorTest, accuracy_1d_odd_fft) { ASSERT_NEAR(phaseShift.x, (double)xShift, 1.); } +////////////////////// DivSpectrums //////////////////////// +class CV_DivSpectrumsTest : public cvtest::ArrayTest +{ +public: + CV_DivSpectrumsTest(); +protected: + void run_func(); + void get_test_array_types_and_sizes( int, vector >& sizes, vector >& types ); + void prepare_to_validation( int test_case_idx ); + int flags; +}; + + +CV_DivSpectrumsTest::CV_DivSpectrumsTest() : flags(0) +{ + // Allocate test matrices. + test_array[INPUT].push_back(NULL); // first input DFT as a CCS-packed array or complex matrix. + test_array[INPUT].push_back(NULL); // second input DFT as a CCS-packed array or complex matrix. + test_array[OUTPUT].push_back(NULL); // output DFT as a complex matrix. + test_array[REF_OUTPUT].push_back(NULL); // reference output DFT as a complex matrix. + test_array[TEMP].push_back(NULL); // first input DFT converted to a complex matrix. + test_array[TEMP].push_back(NULL); // second input DFT converted to a complex matrix. + test_array[TEMP].push_back(NULL); // output DFT as a CCV-packed array. +} + +void CV_DivSpectrumsTest::get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ) +{ + cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx, sizes, types); + RNG& rng = ts->get_rng(); + + // Get the flag of the input. + const int rand_int_flags = cvtest::randInt(rng); + flags = rand_int_flags & (CV_DXT_MUL_CONJ | CV_DXT_ROWS); + + // Get input type. + const int rand_int_type = cvtest::randInt(rng); + int type; + + if (rand_int_type % 4) + { + type = CV_32FC1; + } + else if (rand_int_type % 4 == 1) + { + type = CV_32FC2; + } + else if (rand_int_type % 4 == 2) + { + type = CV_64FC1; + } + else + { + type = CV_64FC2; + } + + for( size_t i = 0; i < types.size(); i++ ) + { + for( size_t j = 0; j < types[i].size(); j++ ) + { + types[i][j] = type; + } + } + + // Inputs are CCS-packed arrays. Prepare outputs and temporary inputs as complex matrices. + if( type == CV_32FC1 || type == CV_64FC1 ) + { + types[OUTPUT][0] += 8; + types[REF_OUTPUT][0] += 8; + types[TEMP][0] += 8; + types[TEMP][1] += 8; + } +} + +/// Helper function to convert a ccs array of depth_t into a complex matrix. +template +static void convert_from_ccs_helper( const Mat& src0, const Mat& src1, Mat& dst ) +{ + const int cn = src0.channels(); + int srcstep = cn; + int dststep = 1; + + if( !dst.isContinuous() ) + dststep = (int)(dst.step/dst.elemSize()); + + if( !src0.isContinuous() ) + srcstep = (int)(src0.step/src0.elemSize1()); + + Complex *dst_data = dst.ptr >(); + const depth_t* src0_data = src0.ptr(); + const depth_t* src1_data = src1.ptr(); + dst_data->re = src0_data[0]; + dst_data->im = 0; + const int n = dst.cols + dst.rows - 1; + const int n2 = (n+1) >> 1; + + if( (n & 1) == 0 ) + { + dst_data[n2*dststep].re = src0_data[(cn == 1 ? n-1 : n2)*srcstep]; + dst_data[n2*dststep].im = 0; + } + + int delta0 = srcstep; + int delta1 = delta0 + (cn == 1 ? srcstep : 1); + + if( cn == 1 ) + srcstep *= 2; + + for( int i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep ) + { + depth_t t0 = src0_data[delta0]; + depth_t t1 = src0_data[delta1]; + + dst_data[i*dststep].re = t0; + dst_data[i*dststep].im = t1; + + t0 = src1_data[delta0]; + t1 = -src1_data[delta1]; + + dst_data[(n-i)*dststep].re = t0; + dst_data[(n-i)*dststep].im = t1; + } +} + +/// Helper function to convert a ccs array into a complex matrix. +static void convert_from_ccs( const Mat& src0, const Mat& src1, Mat& dst, const int flags ) +{ + if( dst.rows > 1 && (dst.cols > 1 || (flags & DFT_ROWS)) ) + { + const int count = dst.rows; + const int len = dst.cols; + const bool is2d = (flags & DFT_ROWS) == 0; + for( int i = 0; i < count; i++ ) + { + const int j = !is2d || i == 0 ? i : count - i; + const Mat& src0row = src0.row(i); + const Mat& src1row = src1.row(j); + Mat dstrow = dst.row(i); + convert_from_ccs( src0row, src1row, dstrow, 0 ); + } + + if( is2d ) + { + const Mat& src0row = src0.col(0); + Mat dstrow = dst.col(0); + convert_from_ccs( src0row, src0row, dstrow, 0 ); + + if( (len & 1) == 0 ) + { + const Mat& src0row_even = src0.col(src0.cols - 1); + Mat dstrow_even = dst.col(len/2); + convert_from_ccs( src0row_even, src0row_even, dstrow_even, 0 ); + } + } + } + else + { + if( dst.depth() == CV_32F ) + { + convert_from_ccs_helper( src0, src1, dst ); + } + else + { + convert_from_ccs_helper( src0, src1, dst ); + } + } +} + +/// Helper function to compute complex number (nu_re + nu_im * i) / (de_re + de_im * i). +static std::pair divide_complex_numbers( const double nu_re, const double nu_im, + const double de_re, const double de_im, + const bool conj_de ) +{ + if ( conj_de ) + { + return divide_complex_numbers( nu_re, nu_im, de_re, -de_im, false /* conj_de */ ); + } + + const double result_de = de_re * de_re + de_im * de_im + DBL_EPSILON; + const double result_re = nu_re * de_re + nu_im * de_im; + const double result_im = nu_re * (-de_im) + nu_im * de_re; + return std::pair(result_re / result_de, result_im / result_de); +}; + +/// Helper function to divide a DFT in src1 by a DFT in src2 with depths depth_t. The DFTs are +/// complex matrices. +template +static void div_complex_helper( const Mat& src1, const Mat& src2, Mat& dst, int flags ) +{ + CV_Assert( src1.size == src2.size && src1.type() == src2.type() ); + dst.create( src1.rows, src1.cols, src1.type() ); + const int cn = src1.channels(); + int cols = src1.cols * cn; + + for( int i = 0; i < dst.rows; i++ ) + { + const depth_t *src1_data = src1.ptr(i); + const depth_t *src2_data = src2.ptr(i); + depth_t *dst_data = dst.ptr(i); + for( int j = 0; j < cols; j += 2 ) + { + std::pair result = + divide_complex_numbers( src1_data[j], src1_data[j + 1], + src2_data[j], src2_data[j + 1], + (flags & CV_DXT_MUL_CONJ) != 0 ); + dst_data[j] = (depth_t)result.first; + dst_data[j + 1] = (depth_t)result.second; + } + } +} + +/// Helper function to divide a DFT in src1 by a DFT in src2. The DFTs are complex matrices. +static void div_complex( const Mat& src1, const Mat& src2, Mat& dst, const int flags ) +{ + const int type = src1.type(); + CV_Assert( type == CV_32FC2 || type == CV_64FC2 ); + + if ( src1.depth() == CV_32F ) + { + return div_complex_helper( src1, src2, dst, flags ); + } + else + { + return div_complex_helper( src1, src2, dst, flags ); + } +} + +void CV_DivSpectrumsTest::prepare_to_validation( int /* test_case_idx */ ) +{ + Mat &src1 = test_mat[INPUT][0]; + Mat &src2 = test_mat[INPUT][1]; + Mat &ref_dst = test_mat[REF_OUTPUT][0]; + const int cn = src1.channels(); + // Inputs are CCS-packed arrays. Convert them to complex matrices and get the expected output + // as a complex matrix. + if( cn == 1 ) + { + Mat &converted_src1 = test_mat[TEMP][0]; + Mat &converted_src2 = test_mat[TEMP][1]; + convert_from_ccs( src1, src1, converted_src1, flags ); + convert_from_ccs( src2, src2, converted_src2, flags ); + div_complex( converted_src1, converted_src2, ref_dst, flags ); + } + // Inputs are complex matrices. Get the expected output as a complex matrix. + else + { + div_complex( src1, src2, ref_dst, flags ); + } +} + +void CV_DivSpectrumsTest::run_func() +{ + const Mat &src1 = test_mat[INPUT][0]; + const Mat &src2 = test_mat[INPUT][1]; + const int cn = src1.channels(); + + // Inputs are CCS-packed arrays. Get the output as a CCS-packed array and convert it to a + // complex matrix. + if ( cn == 1 ) + { + Mat &dst = test_mat[TEMP][2]; + cv::divSpectrums( src1, src2, dst, flags, (flags & CV_DXT_MUL_CONJ) != 0 ); + Mat &converted_dst = test_mat[OUTPUT][0]; + convert_from_ccs( dst, dst, converted_dst, flags ); + } + // Inputs are complex matrices. Get the output as a complex matrix. + else + { + Mat &dst = test_mat[OUTPUT][0]; + cv::divSpectrums( src1, src2, dst, flags, (flags & CV_DXT_MUL_CONJ) != 0 ); + } +} + +TEST(Imgproc_DivSpectrums, accuracy) { CV_DivSpectrumsTest test; test.safe_run(); } + }} // namespace diff --git a/modules/imgproc/test/test_smooth_bitexact.cpp b/modules/imgproc/test/test_smooth_bitexact.cpp index f446deb8d863..246f1df7980b 100644 --- a/modules/imgproc/test/test_smooth_bitexact.cpp +++ b/modules/imgproc/test/test_smooth_bitexact.cpp @@ -220,6 +220,15 @@ TEST(GaussianBlur_Bitexact, regression_15015) ASSERT_EQ(0.0, cvtest::norm(dst, src, NORM_INF)); } +TEST(GaussianBlur_Bitexact, overflow_20121) +{ + Mat src(100, 100, CV_16UC1, Scalar(65535)); + Mat dst; + GaussianBlur(src, dst, cv::Size(9, 9), 0.0); + double min_val; + minMaxLoc(dst, &min_val); + ASSERT_EQ(cvRound(min_val), 65535); +} static void checkGaussianBlur_8Uvs32F(const Mat& src8u, const Mat& src32f, int N, double sigma) { diff --git a/modules/java/android_sdk/android_gradle_lib/build.gradle b/modules/java/android_sdk/android_gradle_lib/build.gradle index 8f969a0a864a..3966c9def6cd 100644 --- a/modules/java/android_sdk/android_gradle_lib/build.gradle +++ b/modules/java/android_sdk/android_gradle_lib/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +@KOTLIN_PLUGIN_DECLARATION@ def openCVersionName = "@OPENCV_VERSION@" def openCVersionCode = ((@OPENCV_VERSION_MAJOR@ * 100 + @OPENCV_VERSION_MINOR@) * 100 + @OPENCV_VERSION_PATCH@) * 10 + 0 diff --git a/modules/java/android_sdk/build.gradle.in b/modules/java/android_sdk/build.gradle.in index 4ff5cd86be23..3ac66b3c79c3 100644 --- a/modules/java/android_sdk/build.gradle.in +++ b/modules/java/android_sdk/build.gradle.in @@ -89,6 +89,7 @@ // apply plugin: 'com.android.library' +@KOTLIN_PLUGIN_DECLARATION@ def openCVersionName = "@OPENCV_VERSION@" def openCVersionCode = ((@OPENCV_VERSION_MAJOR@ * 100 + @OPENCV_VERSION_MINOR@) * 100 + @OPENCV_VERSION_PATCH@) * 10 + 0 diff --git a/modules/java/generator/gen_java.py b/modules/java/generator/gen_java.py index e41117558a26..c5b4f34a8f2b 100755 --- a/modules/java/generator/gen_java.py +++ b/modules/java/generator/gen_java.py @@ -258,6 +258,8 @@ def __init__(self, decl, namespaces=[]): # [ 'class/struct cname', ': base', [mo for m in decl[2]: if m.startswith("="): self.jname = m[1:] + if m == '/Simple': + self.smart = False if self.classpath: prefix = self.classpath.replace('.', '_') @@ -445,7 +447,7 @@ def __init__(self): def clear(self): self.namespaces = ["cv"] - classinfo_Mat = ClassInfo([ 'class cv.Mat', '', [], [] ], self.namespaces) + classinfo_Mat = ClassInfo([ 'class cv.Mat', '', ['/Simple'], [] ], self.namespaces) self.classes = { "Mat" : classinfo_Mat } self.module = "" self.Module = "" @@ -466,10 +468,15 @@ def add_class(self, decl): if name in type_dict and not classinfo.base: logging.warning('duplicated: %s', classinfo) return + if self.isSmartClass(classinfo): + jni_name = "*((*(Ptr<"+classinfo.fullNameCPP()+">*)%(n)s_nativeObj).get())" + else: + jni_name = "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)" type_dict.setdefault(name, {}).update( { "j_type" : classinfo.jname, "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), - "jni_name" : "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)", "jni_type" : "jlong", + "jni_name" : jni_name, + "jni_type" : "jlong", "suffix" : "J", "j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname) } @@ -477,7 +484,8 @@ def add_class(self, decl): type_dict.setdefault(name+'*', {}).update( { "j_type" : classinfo.jname, "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), - "jni_name" : "("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj", "jni_type" : "jlong", + "jni_name" : "&("+jni_name+")", + "jni_type" : "jlong", "suffix" : "J", "j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname) } @@ -966,7 +974,13 @@ def gen_func(self, ci, fi, prop_name=''): ret = "return env->NewStringUTF(_retval_.c_str());" default = 'return env->NewStringUTF("");' elif self.isWrapped(fi.ctype): # wrapped class: - ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype) + ret = None + if fi.ctype in self.classes: + ret_ci = self.classes[fi.ctype] + if self.isSmartClass(ret_ci): + ret = "return (jlong)(new Ptr<%(ctype)s>(new %(ctype)s(_retval_)));" % { 'ctype': ret_ci.fullNameCPP() } + if ret is None: + ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype) elif fi.ctype.startswith('Ptr_'): c_prologue.append("typedef Ptr<%s> %s;" % (self.fullTypeNameCPP(fi.ctype[4:]), fi.ctype)) ret = "return (jlong)(new %(ctype)s(_retval_));" % { 'ctype':fi.ctype } @@ -1207,17 +1221,7 @@ def isSmartClass(self, ci): if ci.smart != None: return ci.smart - # if parents are smart (we hope) then children are! - # if not we believe the class is smart if it has "create" method - ci.smart = False - if ci.base or ci.name == 'Algorithm': - ci.smart = True - else: - for fi in ci.methods: - if fi.name == "create": - ci.smart = True - break - + ci.smart = True # smart class is not properly handled in case of base/derived classes return ci.smart def smartWrap(self, ci, fullname): @@ -1236,13 +1240,13 @@ def finalize(self, output_jni_path): def copy_java_files(java_files_dir, java_base_path, default_package_path='org/opencv/'): global total_files, updated_files java_files = [] - re_filter = re.compile(r'^.+\.(java|aidl)(.in)?$') + re_filter = re.compile(r'^.+\.(java|aidl|kt)(.in)?$') for root, dirnames, filenames in os.walk(java_files_dir): java_files += [os.path.join(root, filename) for filename in filenames if re_filter.match(filename)] java_files = [f.replace('\\', '/') for f in java_files] re_package = re.compile(r'^package +(.+);') - re_prefix = re.compile(r'^.+[\+/]([^\+]+).(java|aidl)(.in)?$') + re_prefix = re.compile(r'^.+[\+/]([^\+]+).(java|aidl|kt)(.in)?$') for java_file in java_files: src = checkFileRemap(java_file) with open(src, 'r') as f: diff --git a/modules/java/test/pure_test/build.xml b/modules/java/test/pure_test/build.xml index 15419f5d6778..e596c82e9dc2 100644 --- a/modules/java/test/pure_test/build.xml +++ b/modules/java/test/pure_test/build.xml @@ -6,6 +6,7 @@ + @@ -53,7 +54,7 @@ - + diff --git a/modules/java/test/pure_test/src/org/opencv/test/OpenCVTestCase.java b/modules/java/test/pure_test/src/org/opencv/test/OpenCVTestCase.java index 3fd918dbfe93..7ed8a41ba86a 100644 --- a/modules/java/test/pure_test/src/org/opencv/test/OpenCVTestCase.java +++ b/modules/java/test/pure_test/src/org/opencv/test/OpenCVTestCase.java @@ -312,6 +312,13 @@ public static void assertArrayEquals(E[] ar1, E[] ar2, double //assertTrue(Math.abs(ar1[i].doubleValue() - ar2[i].doubleValue()) <= epsilon); } + public static void assertArrayEquals(byte[] ar1, byte[] ar2) { + assertEquals(ar1.length, ar2.length); + + for (int i = 0; i < ar1.length; i++) + assertEquals(ar1[i], ar2[i]); + } + public static void assertArrayEquals(short[] ar1, short[] ar2) { assertEquals(ar1.length, ar2.length); diff --git a/modules/objdetect/src/hog.cpp b/modules/objdetect/src/hog.cpp index 5ae912698311..00a182245a3a 100644 --- a/modules/objdetect/src/hog.cpp +++ b/modules/objdetect/src/hog.cpp @@ -120,6 +120,12 @@ void HOGDescriptor::setSVMDetector(InputArray _svmDetector) _svmDetector.getMat().convertTo(svmDetector, CV_32F); CV_Assert(checkDetectorSize()); + if (_svmDetector.empty()) + { + oclSvmDetector = UMat(); + return; + } + Mat detector_reordered(1, (int)svmDetector.size(), CV_32FC1); size_t block_hist_size = getBlockHistogramSize(blockSize, cellSize, nbins); diff --git a/modules/objdetect/test/opencl/test_hogdetector.cpp b/modules/objdetect/test/opencl/test_hogdetector.cpp index 009274096f6f..cffe2e3fb5c9 100644 --- a/modules/objdetect/test/opencl/test_hogdetector.cpp +++ b/modules/objdetect/test/opencl/test_hogdetector.cpp @@ -93,6 +93,25 @@ OCL_TEST_P(HOG, GetDescriptors) EXPECT_MAT_SIMILAR(cpu_desc, gpu_desc, 1e-1); } +OCL_TEST_P(HOG, SVMDetector) +{ + HOGDescriptor hog_first, hog_second; + + // empty -> empty + hog_first.copyTo(hog_second); + + // first -> both + hog_first.setSVMDetector(hog_first.getDefaultPeopleDetector()); + hog_first.copyTo(hog_second); + + // both -> both + hog_first.copyTo(hog_second); + + // second -> empty + hog_first.setSVMDetector(cv::noArray()); + hog_first.copyTo(hog_second); +} + OCL_TEST_P(HOG, Detect) { HOGDescriptor hog; diff --git a/modules/photo/src/merge.cpp b/modules/photo/src/merge.cpp index fbeb4639b43a..e6a00fedb857 100644 --- a/modules/photo/src/merge.cpp +++ b/modules/photo/src/merge.cpp @@ -344,7 +344,7 @@ class MergeRobertsonImpl CV_FINAL : public MergeRobertson result += times.at((int)i) * w.mul(im); wsum += times.at((int)i) * times.at((int)i) * w; } - result = result.mul(1 / wsum); + result = result.mul(1 / (wsum + Scalar::all(DBL_EPSILON))); } void process(InputArrayOfArrays src, OutputArray dst, InputArray times) CV_OVERRIDE diff --git a/modules/photo/test/test_hdr.cpp b/modules/photo/test/test_hdr.cpp index 198b83470cc1..10050abbcbf3 100644 --- a/modules/photo/test/test_hdr.cpp +++ b/modules/photo/test/test_hdr.cpp @@ -249,4 +249,21 @@ TEST(Photo_CalibrateRobertson, regression) checkEqual(expected, response, 1e-1f, "CalibrateRobertson"); } +TEST(Photo_CalibrateRobertson, bug_18180) +{ + vector images; + vector fn; + string test_path = cvtest::TS::ptr()->get_data_path() + "hdr/exposures/bug_18180/"; + for(int i = 1; i <= 4; ++i) + images.push_back(imread(test_path + std::to_string(i) + ".jpg")); + vector times {15.0f, 2.5f, 0.25f, 0.33f}; + Mat response, expected; + Ptr calibrate = createCalibrateRobertson(2, 0.01f); + calibrate->process(images, response, times); + Mat response_no_nans = response.clone(); + patchNaNs(response_no_nans); + // since there should be no NaNs, original response vs. response with NaNs patched should be identical + EXPECT_EQ(0.0, cv::norm(response, response_no_nans, NORM_L2)); +} + }} // namespace diff --git a/modules/python/common.cmake b/modules/python/common.cmake index 1a6cc9742979..0ea4ee7b27a9 100644 --- a/modules/python/common.cmake +++ b/modules/python/common.cmake @@ -232,8 +232,9 @@ if(NOT OPENCV_SKIP_PYTHON_LOADER) if(extra_py_files) list(SORT extra_py_files) foreach(f ${extra_py_files}) + get_filename_component(__dir "${f}" DIRECTORY) configure_file("${__base}/${f}" "${__loader_path}/cv2/_extra_py_code/${f}" COPYONLY) - install(FILES "${__base}/${f}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/_extra_py_code/${f}" COMPONENT python) + install(FILES "${__base}/${f}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/_extra_py_code/${__dir}/" COMPONENT python) endforeach() else() message(WARNING "Module ${m} has no .py files in misc/python/package") diff --git a/modules/python/package/cv2/__init__.py b/modules/python/package/cv2/__init__.py index 27db65eef64d..27e7edd083d4 100644 --- a/modules/python/package/cv2/__init__.py +++ b/modules/python/package/cv2/__init__.py @@ -78,8 +78,20 @@ def load_first_config(fnames, required=True): if DEBUG: print('OpenCV loader: PYTHON_EXTENSIONS_PATHS={}'.format(str(l_vars['PYTHON_EXTENSIONS_PATHS']))) if DEBUG: print('OpenCV loader: BINARIES_PATHS={}'.format(str(l_vars['BINARIES_PATHS']))) + applySysPathWorkaround = False + if hasattr(sys, 'OpenCV_REPLACE_SYS_PATH_0'): + applySysPathWorkaround = True + else: + try: + BASE_DIR = os.path.dirname(LOADER_DIR) + if sys.path[0] == BASE_DIR or os.path.realpath(sys.path[0]) == BASE_DIR: + applySysPathWorkaround = True + except: + if DEBUG: print('OpenCV loader: exception during checking workaround for sys.path[0]') + pass # applySysPathWorkaround is False + for p in reversed(l_vars['PYTHON_EXTENSIONS_PATHS']): - sys.path.insert(1, p) + sys.path.insert(1 if not applySysPathWorkaround else 0, p) if os.name == 'nt': if sys.version_info[:2] >= (3, 8): # https://github.com/python/cpython/pull/12302 diff --git a/modules/python/package/setup.py b/modules/python/package/setup.py index ddb8ca70b092..cb585aa80a2d 100644 --- a/modules/python/package/setup.py +++ b/modules/python/package/setup.py @@ -9,7 +9,7 @@ def main(): os.chdir(SCRIPT_DIR) package_name = 'opencv' - package_version = os.environ.get('OPENCV_VERSION', '4.5.2') # TODO + package_version = os.environ.get('OPENCV_VERSION', '4.5.3') # TODO long_description = 'Open Source Computer Vision Library Python bindings' # TODO diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index 9e8a6ee13bd9..795afb13f276 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -2219,12 +2219,6 @@ static PyMethodDef special_methods[] = { #ifdef HAVE_OPENCV_DNN {"dnn_registerLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_registerLayer), "registerLayer(type, class) -> None"}, {"dnn_unregisterLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_unregisterLayer), "unregisterLayer(type) -> None"}, -#endif -#ifdef HAVE_OPENCV_GAPI - {"GIn", CV_PY_FN_WITH_KW(pyopencv_cv_GIn), "GIn(...) -> GInputProtoArgs"}, - {"GOut", CV_PY_FN_WITH_KW(pyopencv_cv_GOut), "GOut(...) -> GOutputProtoArgs"}, - {"gin", CV_PY_FN_WITH_KW(pyopencv_cv_gin), "gin(...) -> ExtractArgsCallback"}, - {"descr_of", CV_PY_FN_WITH_KW(pyopencv_cv_descr_of), "descr_of(...) -> ExtractMetaCallback"}, #endif {NULL, NULL}, }; diff --git a/modules/python/src2/hdr_parser.py b/modules/python/src2/hdr_parser.py index 412d41a4df3f..1e0f9b3a954d 100755 --- a/modules/python/src2/hdr_parser.py +++ b/modules/python/src2/hdr_parser.py @@ -832,6 +832,7 @@ def parse(self, hname, wmode=True): ("GAPI_EXPORTS_W_SIMPLE","CV_EXPORTS_W_SIMPLE"), ("GAPI_WRAP", "CV_WRAP"), ("GAPI_PROP", "CV_PROP"), + ("GAPI_PROP_RW", "CV_PROP_RW"), ('defined(GAPI_STANDALONE)', '0'), ]) diff --git a/modules/ts/CMakeLists.txt b/modules/ts/CMakeLists.txt index f95bed079383..c1d249ea149a 100644 --- a/modules/ts/CMakeLists.txt +++ b/modules/ts/CMakeLists.txt @@ -41,3 +41,9 @@ endif() if(NOT OPENCV_TESTS_CONFIG_STR STREQUAL "${__content}") file(WRITE "${OPENCV_TESTS_CONFIG_FILE}" "${OPENCV_TESTS_CONFIG_STR}") endif() + +if(OPENCV_DISABLE_THREAD_SUPPORT) + # This is required to disable threads in the ts module, as + # described in `ts_gtest.h`. + ocv_target_compile_definitions(${the_module} PUBLIC GTEST_HAS_PTHREAD=0) +endif() diff --git a/modules/ts/include/opencv2/ts.hpp b/modules/ts/include/opencv2/ts.hpp index ed7491a89ac1..394bc6e0faf9 100644 --- a/modules/ts/include/opencv2/ts.hpp +++ b/modules/ts/include/opencv2/ts.hpp @@ -326,6 +326,7 @@ Mat calcSobelKernel2D( int dx, int dy, int apertureSize, int origin=0 ); Mat calcLaplaceKernel2D( int aperture_size ); void initUndistortMap( const Mat& a, const Mat& k, const Mat& R, const Mat& new_a, Size sz, Mat& mapx, Mat& mapy, int map_type ); +void initInverseRectificationMap( const Mat& a, const Mat& k, const Mat& R, const Mat& new_a, Size sz, Mat& mapx, Mat& mapy, int map_type ); void minMaxLoc(const Mat& src, double* minval, double* maxval, vector* minloc, vector* maxloc, const Mat& mask=Mat()); diff --git a/modules/ts/misc/run.py b/modules/ts/misc/run.py index 2d5de0708ca4..c2e4d6532b7f 100755 --- a/modules/ts/misc/run.py +++ b/modules/ts/misc/run.py @@ -51,6 +51,7 @@ parser.add_argument("--android_propagate_opencv_env", action="store_true", default=False, help="Android: propagate OPENCV* environment variables") parser.add_argument("--serial", metavar="serial number", default="", help="Android: directs command to the USB device or emulator with the given serial number") parser.add_argument("--package", metavar="package", default="", help="Java: run JUnit tests for specified module or Android package") + parser.add_argument("--java_test_exclude", metavar="java_test_exclude", default="", help="Java: Filter out specific JUnit tests") parser.add_argument("--trace", action="store_true", default=False, help="Trace: enable OpenCV tracing") parser.add_argument("--trace_dump", metavar="trace_dump", default=-1, help="Trace: dump highlight calls (specify max entries count, 0 - dump all)") diff --git a/modules/ts/misc/run_suite.py b/modules/ts/misc/run_suite.py index 0420d9a96839..2f382238cd63 100644 --- a/modules/ts/misc/run_suite.py +++ b/modules/ts/misc/run_suite.py @@ -115,6 +115,8 @@ def runTest(self, module, path, logfile, workingDir, args=[]): cmd = [self.cache.ant_executable, "-Dopencv.build.type=%s" % self.cache.build_type] if self.options.package: cmd += ["-Dopencv.test.package=%s" % self.options.package] + if self.options.java_test_exclude: + cmd += ["-Dopencv.test.exclude=%s" % self.options.java_test_exclude] cmd += ["buildAndTest"] ret = execute(cmd, cwd=self.cache.java_test_dir) return None, ret diff --git a/modules/ts/misc/table_formatter.py b/modules/ts/misc/table_formatter.py index 412936950f9a..96bafab72d51 100755 --- a/modules/ts/misc/table_formatter.py +++ b/modules/ts/misc/table_formatter.py @@ -1,7 +1,11 @@ #!/usr/bin/env python from __future__ import print_function -import sys, re, os.path, cgi, stat, math +import sys, re, os.path, stat, math +try: + from html import escape +except ImportError: + from cgi import escape # Python 2.7 from optparse import OptionParser from color import getColorizer, dummyColorizer @@ -23,7 +27,7 @@ def __init__(self, colsNum, props = None): self.props = props def htmlEncode(str): - return '
'.join([cgi.escape(s) for s in str]) + return '
'.join([escape(s) for s in str]) class table(object): def_align = "left" diff --git a/modules/ts/src/ocl_perf.cpp b/modules/ts/src/ocl_perf.cpp index 8dacf219f64b..fe521f2c00d9 100644 --- a/modules/ts/src/ocl_perf.cpp +++ b/modules/ts/src/ocl_perf.cpp @@ -70,7 +70,7 @@ void randu(InputOutputArray dst) cv::randu(dst, -128, 128); else if (dst.depth() == CV_16U) cv::randu(dst, 0, 1024); - else if (dst.depth() == CV_32F || dst.depth() == CV_64F) + else if (dst.depth() == CV_32F || dst.depth() == CV_64F || dst.depth() == CV_16F) cv::randu(dst, -1.0, 1.0); else if (dst.depth() == CV_16S || dst.depth() == CV_32S) cv::randu(dst, -4096, 4096); diff --git a/modules/ts/src/ts_perf.cpp b/modules/ts/src/ts_perf.cpp index 2a9169fd13a5..5a42ca01cdc4 100644 --- a/modules/ts/src/ts_perf.cpp +++ b/modules/ts/src/ts_perf.cpp @@ -1297,7 +1297,7 @@ void TestBase::warmup(cv::InputOutputArray a, WarmUpType wtype) cv::randu(a, -128, 128); else if (depth == CV_16U) cv::randu(a, 0, 1024); - else if (depth == CV_32F || depth == CV_64F) + else if (depth == CV_32F || depth == CV_64F || depth == CV_16F) cv::randu(a, -1.0, 1.0); else if (depth == CV_16S || depth == CV_32S) cv::randu(a, -4096, 4096); diff --git a/modules/video/include/opencv2/video/tracking.hpp b/modules/video/include/opencv2/video/tracking.hpp index af35aaa4e7de..7ec6bc55cd10 100644 --- a/modules/video/include/opencv2/video/tracking.hpp +++ b/modules/video/include/opencv2/video/tracking.hpp @@ -818,6 +818,36 @@ class CV_EXPORTS_W TrackerGOTURN : public Tracker //bool update(InputArray image, CV_OUT Rect& boundingBox) CV_OVERRIDE; }; +class CV_EXPORTS_W TrackerDaSiamRPN : public Tracker +{ +protected: + TrackerDaSiamRPN(); // use ::create() +public: + virtual ~TrackerDaSiamRPN() CV_OVERRIDE; + + struct CV_EXPORTS_W_SIMPLE Params + { + CV_WRAP Params(); + CV_PROP_RW std::string model; + CV_PROP_RW std::string kernel_cls1; + CV_PROP_RW std::string kernel_r1; + CV_PROP_RW int backend; + CV_PROP_RW int target; + }; + + /** @brief Constructor + @param parameters DaSiamRPN parameters TrackerDaSiamRPN::Params + */ + static CV_WRAP + Ptr create(const TrackerDaSiamRPN::Params& parameters = TrackerDaSiamRPN::Params()); + + /** @brief Return tracking score + */ + CV_WRAP virtual float getTrackingScore() = 0; + + //void init(InputArray image, const Rect& boundingBox) CV_OVERRIDE; + //bool update(InputArray image, CV_OUT Rect& boundingBox) CV_OVERRIDE; +}; //! @} video_track diff --git a/modules/video/misc/java/test/TrackerCreateTest.java b/modules/video/misc/java/test/TrackerCreateTest.java index dad696bebfa2..83bbd0b5d5ce 100644 --- a/modules/video/misc/java/test/TrackerCreateTest.java +++ b/modules/video/misc/java/test/TrackerCreateTest.java @@ -1,7 +1,10 @@ package org.opencv.test.video; import org.opencv.core.Core; +import org.opencv.core.CvType; import org.opencv.core.CvException; +import org.opencv.core.Mat; +import org.opencv.core.Rect; import org.opencv.test.OpenCVTestCase; import org.opencv.video.Tracker; @@ -27,6 +30,10 @@ public void testCreateTrackerGOTURN() { public void testCreateTrackerMIL() { Tracker tracker = TrackerMIL.create(); + assert(tracker != null); + Mat mat = new Mat(100, 100, CvType.CV_8UC1); + Rect rect = new Rect(10, 10, 30, 30); + tracker.init(mat, rect); // should not crash (https://github.com/opencv/opencv/issues/19915) } } diff --git a/modules/video/misc/python/pyopencv_video.hpp b/modules/video/misc/python/pyopencv_video.hpp index 761905c8bf3f..ea8977911f3f 100644 --- a/modules/video/misc/python/pyopencv_video.hpp +++ b/modules/video/misc/python/pyopencv_video.hpp @@ -1,4 +1,5 @@ #ifdef HAVE_OPENCV_VIDEO typedef TrackerMIL::Params TrackerMIL_Params; typedef TrackerGOTURN::Params TrackerGOTURN_Params; +typedef TrackerDaSiamRPN::Params TrackerDaSiamRPN_Params; #endif diff --git a/modules/video/src/tracking/tracker_dasiamrpn.cpp b/modules/video/src/tracking/tracker_dasiamrpn.cpp new file mode 100644 index 000000000000..72e0aa1f3a28 --- /dev/null +++ b/modules/video/src/tracking/tracker_dasiamrpn.cpp @@ -0,0 +1,440 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include "../precomp.hpp" + +#ifdef HAVE_OPENCV_DNN +#include "opencv2/dnn.hpp" +#endif + +namespace cv { + +TrackerDaSiamRPN::TrackerDaSiamRPN() +{ + // nothing +} + +TrackerDaSiamRPN::~TrackerDaSiamRPN() +{ + // nothing +} + +TrackerDaSiamRPN::Params::Params() +{ + model = "dasiamrpn_model.onnx"; + kernel_cls1 = "dasiamrpn_kernel_cls1.onnx"; + kernel_r1 = "dasiamrpn_kernel_r1.onnx"; +#ifdef HAVE_OPENCV_DNN + backend = dnn::DNN_BACKEND_DEFAULT; + target = dnn::DNN_TARGET_CPU; +#else + backend = -1; // invalid value + target = -1; // invalid value +#endif +} + +#ifdef HAVE_OPENCV_DNN + +template static +T sizeCal(const T& w, const T& h) +{ + T pad = (w + h) * T(0.5); + T sz2 = (w + pad) * (h + pad); + return sqrt(sz2); +} + +template <> +Mat sizeCal(const Mat& w, const Mat& h) +{ + Mat pad = (w + h) * 0.5; + Mat sz2 = (w + pad).mul((h + pad)); + + cv::sqrt(sz2, sz2); + return sz2; +} + +class TrackerDaSiamRPNImpl : public TrackerDaSiamRPN +{ +public: + TrackerDaSiamRPNImpl(const TrackerDaSiamRPN::Params& parameters) + : params(parameters) + { + + siamRPN = dnn::readNet(params.model); + siamKernelCL1 = dnn::readNet(params.kernel_cls1); + siamKernelR1 = dnn::readNet(params.kernel_r1); + + CV_Assert(!siamRPN.empty()); + CV_Assert(!siamKernelCL1.empty()); + CV_Assert(!siamKernelR1.empty()); + + siamRPN.setPreferableBackend(params.backend); + siamRPN.setPreferableTarget(params.target); + siamKernelR1.setPreferableBackend(params.backend); + siamKernelR1.setPreferableTarget(params.target); + siamKernelCL1.setPreferableBackend(params.backend); + siamKernelCL1.setPreferableTarget(params.target); + } + + void init(InputArray image, const Rect& boundingBox) CV_OVERRIDE; + bool update(InputArray image, Rect& boundingBox) CV_OVERRIDE; + float getTrackingScore() CV_OVERRIDE; + + TrackerDaSiamRPN::Params params; + +protected: + dnn::Net siamRPN, siamKernelR1, siamKernelCL1; + Rect boundingBox_; + Mat image_; + struct trackerConfig + { + float windowInfluence = 0.43f; + float lr = 0.4f; + int scale = 8; + bool swapRB = false; + int totalStride = 8; + float penaltyK = 0.055f; + int exemplarSize = 127; + int instanceSize = 271; + float contextAmount = 0.5f; + std::vector ratios = { 0.33f, 0.5f, 1.0f, 2.0f, 3.0f }; + int anchorNum = int(ratios.size()); + Mat anchors; + Mat windows; + Scalar avgChans; + Size imgSize = { 0, 0 }; + Rect2f targetBox = { 0, 0, 0, 0 }; + int scoreSize = (instanceSize - exemplarSize) / totalStride + 1; + float tracking_score; + + void update_scoreSize() + { + scoreSize = int((instanceSize - exemplarSize) / totalStride + 1); + } + }; + trackerConfig trackState; + + void softmax(const Mat& src, Mat& dst); + void elementMax(Mat& src); + Mat generateHanningWindow(); + Mat generateAnchors(); + Mat getSubwindow(Mat& img, const Rect2f& targetBox, float originalSize, Scalar avgChans); + void trackerInit(Mat img); + void trackerEval(Mat img); +}; + +void TrackerDaSiamRPNImpl::init(InputArray image, const Rect& boundingBox) +{ + image_ = image.getMat().clone(); + + trackState.update_scoreSize(); + trackState.targetBox = Rect2f( + float(boundingBox.x) + float(boundingBox.width) * 0.5f, // FIXIT don't use center in Rect structures, it is confusing + float(boundingBox.y) + float(boundingBox.height) * 0.5f, + float(boundingBox.width), + float(boundingBox.height) + ); + trackerInit(image_); +} + +void TrackerDaSiamRPNImpl::trackerInit(Mat img) +{ + Rect2f targetBox = trackState.targetBox; + Mat anchors = generateAnchors(); + trackState.anchors = anchors; + + Mat windows = generateHanningWindow(); + + trackState.windows = windows; + trackState.imgSize = img.size(); + + trackState.avgChans = mean(img); + float wc = targetBox.width + trackState.contextAmount * (targetBox.width + targetBox.height); + float hc = targetBox.height + trackState.contextAmount * (targetBox.width + targetBox.height); + float sz = (float)cvRound(sqrt(wc * hc)); + + Mat zCrop = getSubwindow(img, targetBox, sz, trackState.avgChans); + Mat blob; + + dnn::blobFromImage(zCrop, blob, 1.0, Size(trackState.exemplarSize, trackState.exemplarSize), Scalar(), trackState.swapRB, false, CV_32F); + siamRPN.setInput(blob); + Mat out1; + siamRPN.forward(out1, "63"); + + siamKernelCL1.setInput(out1); + siamKernelR1.setInput(out1); + + Mat cls1 = siamKernelCL1.forward(); + Mat r1 = siamKernelR1.forward(); + std::vector r1_shape = { 20, 256, 4, 4 }, cls1_shape = { 10, 256, 4, 4 }; + + siamRPN.setParam(siamRPN.getLayerId("65"), 0, r1.reshape(0, r1_shape)); + siamRPN.setParam(siamRPN.getLayerId("68"), 0, cls1.reshape(0, cls1_shape)); +} + +bool TrackerDaSiamRPNImpl::update(InputArray image, Rect& boundingBox) +{ + image_ = image.getMat().clone(); + trackerEval(image_); + boundingBox = { + int(trackState.targetBox.x - int(trackState.targetBox.width / 2)), + int(trackState.targetBox.y - int(trackState.targetBox.height / 2)), + int(trackState.targetBox.width), + int(trackState.targetBox.height) + }; + return true; +} + +void TrackerDaSiamRPNImpl::trackerEval(Mat img) +{ + Rect2f targetBox = trackState.targetBox; + + float wc = targetBox.height + trackState.contextAmount * (targetBox.width + targetBox.height); + float hc = targetBox.width + trackState.contextAmount * (targetBox.width + targetBox.height); + + float sz = sqrt(wc * hc); + float scaleZ = trackState.exemplarSize / sz; + + float searchSize = float((trackState.instanceSize - trackState.exemplarSize) / 2); + float pad = searchSize / scaleZ; + float sx = sz + 2 * pad; + + Mat xCrop = getSubwindow(img, targetBox, (float)cvRound(sx), trackState.avgChans); + + Mat blob; + std::vector outs; + std::vector outNames; + Mat delta, score; + Mat sc, rc, penalty, pscore; + + dnn::blobFromImage(xCrop, blob, 1.0, Size(trackState.instanceSize, trackState.instanceSize), Scalar(), trackState.swapRB, false, CV_32F); + + siamRPN.setInput(blob); + + outNames = siamRPN.getUnconnectedOutLayersNames(); + siamRPN.forward(outs, outNames); + + delta = outs[0]; + score = outs[1]; + + score = score.reshape(0, { 2, trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); + delta = delta.reshape(0, { 4, trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); + + softmax(score, score); + + targetBox.width *= scaleZ; + targetBox.height *= scaleZ; + + score = score.row(1); + score = score.reshape(0, { 5, 19, 19 }); + + // Post processing + delta.row(0) = delta.row(0).mul(trackState.anchors.row(2)) + trackState.anchors.row(0); + delta.row(1) = delta.row(1).mul(trackState.anchors.row(3)) + trackState.anchors.row(1); + exp(delta.row(2), delta.row(2)); + delta.row(2) = delta.row(2).mul(trackState.anchors.row(2)); + exp(delta.row(3), delta.row(3)); + delta.row(3) = delta.row(3).mul(trackState.anchors.row(3)); + + sc = sizeCal(delta.row(2), delta.row(3)) / sizeCal(targetBox.width, targetBox.height); + elementMax(sc); + + rc = delta.row(2).mul(1 / delta.row(3)); + rc = (targetBox.width / targetBox.height) / rc; + elementMax(rc); + + // Calculating the penalty + exp(((rc.mul(sc) - 1.) * trackState.penaltyK * (-1.0)), penalty); + penalty = penalty.reshape(0, { trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); + + pscore = penalty.mul(score); + pscore = pscore * (1.0 - trackState.windowInfluence) + trackState.windows * trackState.windowInfluence; + + int bestID[2] = { 0, 0 }; + // Find the index of best score. + minMaxIdx(pscore.reshape(0, { trackState.anchorNum * trackState.scoreSize * trackState.scoreSize, 1 }), 0, 0, 0, bestID); + delta = delta.reshape(0, { 4, trackState.anchorNum * trackState.scoreSize * trackState.scoreSize }); + penalty = penalty.reshape(0, { trackState.anchorNum * trackState.scoreSize * trackState.scoreSize, 1 }); + score = score.reshape(0, { trackState.anchorNum * trackState.scoreSize * trackState.scoreSize, 1 }); + + int index[2] = { 0, bestID[0] }; + Rect2f resBox = { 0, 0, 0, 0 }; + + resBox.x = delta.at(index) / scaleZ; + index[0] = 1; + resBox.y = delta.at(index) / scaleZ; + index[0] = 2; + resBox.width = delta.at(index) / scaleZ; + index[0] = 3; + resBox.height = delta.at(index) / scaleZ; + + float lr = penalty.at(bestID) * score.at(bestID) * trackState.lr; + + resBox.x = resBox.x + targetBox.x; + resBox.y = resBox.y + targetBox.y; + targetBox.width /= scaleZ; + targetBox.height /= scaleZ; + + resBox.width = targetBox.width * (1 - lr) + resBox.width * lr; + resBox.height = targetBox.height * (1 - lr) + resBox.height * lr; + + resBox.x = float(fmax(0., fmin(float(trackState.imgSize.width), resBox.x))); + resBox.y = float(fmax(0., fmin(float(trackState.imgSize.height), resBox.y))); + resBox.width = float(fmax(10., fmin(float(trackState.imgSize.width), resBox.width))); + resBox.height = float(fmax(10., fmin(float(trackState.imgSize.height), resBox.height))); + + trackState.targetBox = resBox; + trackState.tracking_score = score.at(bestID); +} + +float TrackerDaSiamRPNImpl::getTrackingScore() +{ + return trackState.tracking_score; +} + +void TrackerDaSiamRPNImpl::softmax(const Mat& src, Mat& dst) +{ + Mat maxVal; + cv::max(src.row(1), src.row(0), maxVal); + + src.row(1) -= maxVal; + src.row(0) -= maxVal; + + exp(src, dst); + + Mat sumVal = dst.row(0) + dst.row(1); + dst.row(0) = dst.row(0) / sumVal; + dst.row(1) = dst.row(1) / sumVal; +} + +void TrackerDaSiamRPNImpl::elementMax(Mat& src) +{ + int* p = src.size.p; + int index[4] = { 0, 0, 0, 0 }; + for (int n = 0; n < *p; n++) + { + for (int k = 0; k < *(p + 1); k++) + { + for (int i = 0; i < *(p + 2); i++) + { + for (int j = 0; j < *(p + 3); j++) + { + index[0] = n, index[1] = k, index[2] = i, index[3] = j; + float& v = src.at(index); + v = fmax(v, 1.0f / v); + } + } + } + } +} + +Mat TrackerDaSiamRPNImpl::generateHanningWindow() +{ + Mat baseWindows, HanningWindows; + + createHanningWindow(baseWindows, Size(trackState.scoreSize, trackState.scoreSize), CV_32F); + baseWindows = baseWindows.reshape(0, { 1, trackState.scoreSize, trackState.scoreSize }); + HanningWindows = baseWindows.clone(); + for (int i = 1; i < trackState.anchorNum; i++) + { + HanningWindows.push_back(baseWindows); + } + + return HanningWindows; +} + +Mat TrackerDaSiamRPNImpl::generateAnchors() +{ + int totalStride = trackState.totalStride, scales = trackState.scale, scoreSize = trackState.scoreSize; + std::vector ratios = trackState.ratios; + std::vector baseAnchors; + int anchorNum = int(ratios.size()); + int size = totalStride * totalStride; + + float ori = -(float(scoreSize / 2)) * float(totalStride); + + for (auto i = 0; i < anchorNum; i++) + { + int ws = int(sqrt(size / ratios[i])); + int hs = int(ws * ratios[i]); + + float wws = float(ws) * scales; + float hhs = float(hs) * scales; + Rect2f anchor = { 0, 0, wws, hhs }; + baseAnchors.push_back(anchor); + } + + int anchorIndex[4] = { 0, 0, 0, 0 }; + const int sizes[4] = { 4, (int)ratios.size(), scoreSize, scoreSize }; + Mat anchors(4, sizes, CV_32F); + + for (auto i = 0; i < scoreSize; i++) + { + for (auto j = 0; j < scoreSize; j++) + { + for (auto k = 0; k < anchorNum; k++) + { + anchorIndex[0] = 1, anchorIndex[1] = k, anchorIndex[2] = i, anchorIndex[3] = j; + anchors.at(anchorIndex) = ori + totalStride * i; + + anchorIndex[0] = 0; + anchors.at(anchorIndex) = ori + totalStride * j; + + anchorIndex[0] = 2; + anchors.at(anchorIndex) = baseAnchors[k].width; + + anchorIndex[0] = 3; + anchors.at(anchorIndex) = baseAnchors[k].height; + } + } + } + + return anchors; +} + +Mat TrackerDaSiamRPNImpl::getSubwindow(Mat& img, const Rect2f& targetBox, float originalSize, Scalar avgChans) +{ + Mat zCrop, dst; + Size imgSize = img.size(); + float c = (originalSize + 1) / 2; + float xMin = (float)cvRound(targetBox.x - c); + float xMax = xMin + originalSize - 1; + float yMin = (float)cvRound(targetBox.y - c); + float yMax = yMin + originalSize - 1; + + int leftPad = (int)(fmax(0., -xMin)); + int topPad = (int)(fmax(0., -yMin)); + int rightPad = (int)(fmax(0., xMax - imgSize.width + 1)); + int bottomPad = (int)(fmax(0., yMax - imgSize.height + 1)); + + xMin = xMin + leftPad; + xMax = xMax + leftPad; + yMax = yMax + topPad; + yMin = yMin + topPad; + + if (topPad == 0 && bottomPad == 0 && leftPad == 0 && rightPad == 0) + { + img(Rect(int(xMin), int(yMin), int(xMax - xMin + 1), int(yMax - yMin + 1))).copyTo(zCrop); + } + else + { + copyMakeBorder(img, dst, topPad, bottomPad, leftPad, rightPad, BORDER_CONSTANT, avgChans); + dst(Rect(int(xMin), int(yMin), int(xMax - xMin + 1), int(yMax - yMin + 1))).copyTo(zCrop); + } + + return zCrop; +} +Ptr TrackerDaSiamRPN::create(const TrackerDaSiamRPN::Params& parameters) +{ + return makePtr(parameters); +} + +#else // OPENCV_HAVE_DNN +Ptr TrackerDaSiamRPN::create(const TrackerDaSiamRPN::Params& parameters) +{ + (void)(parameters); + CV_Error(cv::Error::StsNotImplemented, "to use GOTURN, the tracking module needs to be built with opencv_dnn !"); +} +#endif // OPENCV_HAVE_DNN +} diff --git a/modules/video/test/test_trackers.cpp b/modules/video/test/test_trackers.cpp index 7fd04701819e..2d0e1844085c 100644 --- a/modules/video/test/test_trackers.cpp +++ b/modules/video/test/test_trackers.cpp @@ -94,4 +94,36 @@ TEST(GOTURN, memory_usage) } } +TEST(DaSiamRPN, memory_usage) +{ + cv::Rect roi(145, 70, 85, 85); + + std::string model = cvtest::findDataFile("dnn/onnx/models/dasiamrpn_model.onnx", false); + std::string kernel_r1 = cvtest::findDataFile("dnn/onnx/models/dasiamrpn_kernel_r1.onnx", false); + std::string kernel_cls1 = cvtest::findDataFile("dnn/onnx/models/dasiamrpn_kernel_cls1.onnx", false); + cv::TrackerDaSiamRPN::Params params; + params.model = model; + params.kernel_r1 = kernel_r1; + params.kernel_cls1 = kernel_cls1; + cv::Ptr tracker = TrackerDaSiamRPN::create(params); + + string inputVideo = cvtest::findDataFile("tracking/david/data/david.webm"); + cv::VideoCapture video(inputVideo); + ASSERT_TRUE(video.isOpened()) << inputVideo; + + cv::Mat frame; + video >> frame; + ASSERT_FALSE(frame.empty()) << inputVideo; + tracker->init(frame, roi); + string ground_truth_bb; + for (int nframes = 0; nframes < 15; ++nframes) + { + std::cout << "Frame: " << nframes << std::endl; + video >> frame; + bool res = tracker->update(frame, roi); + ASSERT_TRUE(res); + std::cout << "Predicted ROI: " << roi << std::endl; + } +} + }} // namespace opencv_test:: diff --git a/modules/videoio/src/cap_dshow.cpp b/modules/videoio/src/cap_dshow.cpp index d3abc3694f20..175f1d032952 100644 --- a/modules/videoio/src/cap_dshow.cpp +++ b/modules/videoio/src/cap_dshow.cpp @@ -2503,7 +2503,10 @@ static void findClosestSizeAndSubtype(videoDevice * VD, int widthIn, int heightI int tempH = 999999; //Don't want to get stuck in a loop - if(stepX < 1 || stepY < 1) continue; + if(stepX < 1 || stepY < 1){ + MyDeleteMediaType(pmtConfig); + continue; + } //DebugPrintOut("min is %i %i max is %i %i - res is %i %i\n", scc.MinOutputSize.cx, scc.MinOutputSize.cy, scc.MaxOutputSize.cx, scc.MaxOutputSize.cy, stepX, stepY); //DebugPrintOut("min frame duration is %i max duration is %i\n", scc.MinFrameInterval, scc.MaxFrameInterval); @@ -2619,7 +2622,8 @@ static bool setSizeAndSubtype(videoDevice * VD, int attemptWidth, int attemptHei return true; }else{ VD->streamConf->SetFormat(tmpType); - if( tmpType != NULL )MyDeleteMediaType(tmpType); + if( VD->pAmMediaType != NULL)MyDeleteMediaType(VD->pAmMediaType); + VD->pAmMediaType = tmpType; } return false; diff --git a/modules/videoio/src/cap_msmf.cpp b/modules/videoio/src/cap_msmf.cpp index 73288c3d03b1..9e45fd1bacce 100644 --- a/modules/videoio/src/cap_msmf.cpp +++ b/modules/videoio/src/cap_msmf.cpp @@ -708,9 +708,10 @@ bool CvCapture_MSMF::initStream(DWORD streamID, const MediaType& mt) _ComPtr CvCapture_MSMF::getDefaultSourceConfig(UINT32 num) { CV_Assert(num > 0); + const bool OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS = utils::getConfigurationParameterBool("OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS", true); _ComPtr res; if (FAILED(MFCreateAttributes(&res, num)) || - FAILED(res->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) || + FAILED(res->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS)) || FAILED(res->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) || FAILED(res->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) || FAILED(res->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true)) diff --git a/modules/videoio/test/test_video_io.cpp b/modules/videoio/test/test_video_io.cpp index 3934dedf610c..8b6b16e16e31 100644 --- a/modules/videoio/test/test_video_io.cpp +++ b/modules/videoio/test/test_video_io.cpp @@ -743,13 +743,31 @@ TEST_P(videocapture_acceleration, read) if (use_umat) { UMat umat; - EXPECT_TRUE(hw_reader.read(umat)); + bool read_umat_result = hw_reader.read(umat); + if (!read_umat_result && i == 0) + { + if (filename == "sample_322x242_15frames.yuv420p.libvpx-vp9.mp4") + throw SkipTestException("Unable to read the first frame with VP9 codec (media stack misconfiguration / bug)"); + // FFMPEG: [av1 @ 0000027ac07d1340] Your platform doesn't suppport hardware accelerated AV1 decoding. + if (filename == "sample_322x242_15frames.yuv420p.libaom-av1.mp4") + throw SkipTestException("Unable to read the first frame with AV1 codec (missing support)"); + } + EXPECT_TRUE(read_umat_result); ASSERT_FALSE(umat.empty()); umat.copyTo(frame); } else { - EXPECT_TRUE(hw_reader.read(frame)); + bool read_result = hw_reader.read(frame); + if (!read_result && i == 0) + { + if (filename == "sample_322x242_15frames.yuv420p.libvpx-vp9.mp4") + throw SkipTestException("Unable to read the first frame with VP9 codec (media stack misconfiguration / bug)"); + // FFMPEG: [av1 @ 0000027ac07d1340] Your platform doesn't suppport hardware accelerated AV1 decoding. + if (filename == "sample_322x242_15frames.yuv420p.libaom-av1.mp4") + throw SkipTestException("Unable to read the first frame with AV1 codec (missing support)"); + } + EXPECT_TRUE(read_result); } ASSERT_FALSE(frame.empty()); diff --git a/platforms/android/build_sdk.py b/platforms/android/build_sdk.py index 7d898e4c366b..88cb5ff87f26 100755 --- a/platforms/android/build_sdk.py +++ b/platforms/android/build_sdk.py @@ -159,6 +159,7 @@ def __init__(self, workdir, opencvdir, config): self.debug_info = True if config.debug_info else False self.no_samples_build = True if config.no_samples_build else False self.opencl = True if config.opencl else False + self.no_kotlin = True if config.no_kotlin else False def get_cmake(self): if not self.config.use_android_buildtools and check_executable(['cmake', '--version']): @@ -219,6 +220,7 @@ def build_library(self, abi, do_install): CMAKE_TOOLCHAIN_FILE=self.get_toolchain_file(), INSTALL_CREATE_DISTRIB="ON", WITH_OPENCL="OFF", + BUILD_KOTLIN_EXTENSIONS="ON", WITH_IPP=("ON" if abi.haveIPP() else "OFF"), WITH_TBB="ON", BUILD_EXAMPLES="OFF", @@ -240,6 +242,9 @@ def build_library(self, abi, do_install): if self.opencl: cmake_vars['WITH_OPENCL'] = "ON" + if self.no_kotlin: + cmake_vars['BUILD_KOTLIN_EXTENSIONS'] = "OFF" + if self.config.modules_list is not None: cmd.append("-DBUILD_LIST='%s'" % self.config.modules_list) @@ -359,6 +364,7 @@ def get_ndk_dir(): parser.add_argument('--debug_info', action="store_true", help="Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)") parser.add_argument('--no_samples_build', action="store_true", help="Do not build samples (speeds up build)") parser.add_argument('--opencl', action="store_true", help="Enable OpenCL support") + parser.add_argument('--no_kotlin', action="store_true", help="Disable Kotlin extensions") args = parser.parse_args() log.basicConfig(format='%(message)s', level=log.DEBUG) diff --git a/platforms/android/ndk-22.config.py b/platforms/android/ndk-22.config.py index 69321e0f0c5e..95ab8b172de4 100644 --- a/platforms/android/ndk-22.config.py +++ b/platforms/android/ndk-22.config.py @@ -1,6 +1,6 @@ ABIs = [ - ABI("2", "armeabi-v7a", None, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON', ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5')), - ABI("3", "arm64-v8a", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5')), - ABI("5", "x86_64", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5')), - ABI("4", "x86", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5')), + ABI("2", "armeabi-v7a", None, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON', ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')), + ABI("3", "arm64-v8a", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')), + ABI("5", "x86_64", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')), + ABI("4", "x86", None, cmake_vars=dict(ANDROID_GRADLE_PLUGIN_VERSION='4.1.2', GRADLE_VERSION='6.5', KOTLIN_PLUGIN_VERSION='1.5.10')), ] diff --git a/platforms/linux/riscv64-071-gcc.toolchain.cmake b/platforms/linux/riscv64-071-gcc.toolchain.cmake new file mode 100644 index 000000000000..be2c7dcda9b0 --- /dev/null +++ b/platforms/linux/riscv64-071-gcc.toolchain.cmake @@ -0,0 +1,9 @@ +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_C_COMPILER riscv64-unknown-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER riscv64-unknown-linux-gnu-g++) + +set(CMAKE_CXX_FLAGS "" CACHE STRING "") +set(CMAKE_C_FLAGS "" CACHE STRING "") + +set(CMAKE_CXX_FLAGS "-static -march=rv64gcvxthead -mabi=lp64v -pthread -D__riscv_vector_071") +set(CMAKE_C_FLAGS "-static -march=rv64gcvxthead -mabi=lp64v -pthread -D__riscv_vector_071") diff --git a/platforms/maven/opencv-it/pom.xml b/platforms/maven/opencv-it/pom.xml index efb234fa0393..1166eee2fb16 100644 --- a/platforms/maven/opencv-it/pom.xml +++ b/platforms/maven/opencv-it/pom.xml @@ -4,7 +4,7 @@ org.opencv opencv-parent - 4.5.2 + 4.5.3 org.opencv opencv-it diff --git a/platforms/maven/opencv/pom.xml b/platforms/maven/opencv/pom.xml index ca95f4b74d6f..4ac2c2b7f5c4 100644 --- a/platforms/maven/opencv/pom.xml +++ b/platforms/maven/opencv/pom.xml @@ -4,7 +4,7 @@ org.opencv opencv-parent - 4.5.2 + 4.5.3 org.opencv opencv diff --git a/platforms/maven/pom.xml b/platforms/maven/pom.xml index 42de60ab09ee..72f4f82b1ce1 100644 --- a/platforms/maven/pom.xml +++ b/platforms/maven/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.opencv opencv-parent - 4.5.2 + 4.5.3 pom OpenCV Parent POM diff --git a/platforms/winpack_dldt/2021.4/20210630-dldt-disable-multidevice-autoplugin.patch b/platforms/winpack_dldt/2021.4/20210630-dldt-disable-multidevice-autoplugin.patch new file mode 100644 index 000000000000..f1e748744277 --- /dev/null +++ b/platforms/winpack_dldt/2021.4/20210630-dldt-disable-multidevice-autoplugin.patch @@ -0,0 +1,16 @@ +diff --git a/inference-engine/src/CMakeLists.txt b/inference-engine/src/CMakeLists.txt +index 0ba0dd78..7d34e7cb 100644 +--- a/inference-engine/src/CMakeLists.txt ++++ b/inference-engine/src/CMakeLists.txt +@@ -26,9 +26,9 @@ endif() + + add_subdirectory(hetero_plugin) + +-add_subdirectory(auto_plugin) ++#add_subdirectory(auto_plugin) + +-add_subdirectory(multi_device) ++#add_subdirectory(multi_device) + + add_subdirectory(transformations) + diff --git a/platforms/winpack_dldt/2021.4/20210630-dldt-disable-unused-targets.patch b/platforms/winpack_dldt/2021.4/20210630-dldt-disable-unused-targets.patch new file mode 100644 index 000000000000..9d44cdadc6cd --- /dev/null +++ b/platforms/winpack_dldt/2021.4/20210630-dldt-disable-unused-targets.patch @@ -0,0 +1,219 @@ +diff --git a/cmake/developer_package/add_ie_target.cmake b/cmake/developer_package/add_ie_target.cmake +index d49f16a4d..2726ca787 100644 +--- a/cmake/developer_package/add_ie_target.cmake ++++ b/cmake/developer_package/add_ie_target.cmake +@@ -92,7 +92,7 @@ function(addIeTarget) + if (ARG_TYPE STREQUAL EXECUTABLE) + add_executable(${ARG_NAME} ${all_sources}) + elseif(ARG_TYPE STREQUAL STATIC OR ARG_TYPE STREQUAL SHARED) +- add_library(${ARG_NAME} ${ARG_TYPE} ${all_sources}) ++ add_library(${ARG_NAME} ${ARG_TYPE} EXCLUDE_FROM_ALL ${all_sources}) + else() + message(SEND_ERROR "Invalid target type ${ARG_TYPE} specified for target name ${ARG_NAME}") + endif() +diff --git a/inference-engine/CMakeLists.txt b/inference-engine/CMakeLists.txt +index 1ac7fd8bf..df7091e51 100644 +--- a/inference-engine/CMakeLists.txt ++++ b/inference-engine/CMakeLists.txt +@@ -39,7 +39,7 @@ if(ENABLE_TESTS) + add_subdirectory(tests) + endif() + +-add_subdirectory(tools) ++#add_subdirectory(tools) + + function(ie_build_samples) + # samples should be build with the same flags as from OpenVINO package, +@@ -58,7 +58,7 @@ endfunction() + + # gflags and format_reader targets are kept inside of samples directory and + # they must be built even if samples build is disabled (required for tests and tools). +-ie_build_samples() ++#ie_build_samples() + + if(ENABLE_PYTHON) + add_subdirectory(ie_bridges/python) +@@ -142,7 +142,7 @@ endif() + # Developer package + # + +-openvino_developer_export_targets(COMPONENT openvino_common TARGETS format_reader gflags ie_samples_utils) ++#openvino_developer_export_targets(COMPONENT openvino_common TARGETS format_reader gflags ie_samples_utils) + + # for Template plugin + if(NGRAPH_INTERPRETER_ENABLE) +@@ -166,7 +166,7 @@ function(ie_generate_dev_package_config) + @ONLY) + endfunction() + +-ie_generate_dev_package_config() ++#ie_generate_dev_package_config() + + # + # Coverage +diff --git a/inference-engine/src/inference_engine/CMakeLists.txt b/inference-engine/src/inference_engine/CMakeLists.txt +index e8ed1a5c4..1fc9fc3ff 100644 +--- a/inference-engine/src/inference_engine/CMakeLists.txt ++++ b/inference-engine/src/inference_engine/CMakeLists.txt +@@ -110,7 +110,7 @@ add_cpplint_target(${TARGET_NAME}_plugin_api_cpplint FOR_SOURCES ${plugin_api_sr + + # Create object library + +-add_library(${TARGET_NAME}_obj OBJECT ++add_library(${TARGET_NAME}_obj OBJECT EXCLUDE_FROM_ALL + ${LIBRARY_SRC} + ${LIBRARY_HEADERS} + ${PUBLIC_HEADERS}) +@@ -181,7 +181,7 @@ ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME}) + + # Static library used for unit tests which are always built + +-add_library(${TARGET_NAME}_s STATIC ++add_library(${TARGET_NAME}_s STATIC EXCLUDE_FROM_ALL + $ + $ + ${IE_STATIC_DEPENDENT_FILES}) +diff --git a/inference-engine/src/legacy_api/CMakeLists.txt b/inference-engine/src/legacy_api/CMakeLists.txt +index 8eae82bd2..e0e6745b1 100644 +--- a/inference-engine/src/legacy_api/CMakeLists.txt ++++ b/inference-engine/src/legacy_api/CMakeLists.txt +@@ -26,7 +26,7 @@ endif() + + file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp) + +-add_library(${TARGET_NAME}_obj OBJECT ++add_library(${TARGET_NAME}_obj OBJECT EXCLUDE_FROM_ALL + ${LIBRARY_SRC} + ${PUBLIC_HEADERS}) + +diff --git a/inference-engine/src/mkldnn_plugin/CMakeLists.txt b/inference-engine/src/mkldnn_plugin/CMakeLists.txt +index fe57b29dd..07831e2fb 100644 +--- a/inference-engine/src/mkldnn_plugin/CMakeLists.txt ++++ b/inference-engine/src/mkldnn_plugin/CMakeLists.txt +@@ -67,7 +67,7 @@ ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME}) + + # add test object library + +-add_library(${TARGET_NAME}_obj OBJECT ${SOURCES} ${HEADERS}) ++add_library(${TARGET_NAME}_obj OBJECT EXCLUDE_FROM_ALL ${SOURCES} ${HEADERS}) + target_link_libraries(${TARGET_NAME}_obj PUBLIC mkldnn) + + target_include_directories(${TARGET_NAME}_obj PRIVATE $ +diff --git a/inference-engine/src/preprocessing/CMakeLists.txt b/inference-engine/src/preprocessing/CMakeLists.txt +index f9548339d..ef962145a 100644 +--- a/inference-engine/src/preprocessing/CMakeLists.txt ++++ b/inference-engine/src/preprocessing/CMakeLists.txt +@@ -101,7 +101,7 @@ endif() + + # Create object library + +-add_library(${TARGET_NAME}_obj OBJECT ++add_library(${TARGET_NAME}_obj OBJECT EXCLUDE_FROM_ALL + ${LIBRARY_SRC} + ${LIBRARY_HEADERS}) + +@@ -153,7 +153,7 @@ ie_add_api_validator_post_build_step(TARGET ${TARGET_NAME}) + + # Static library used for unit tests which are always built + +-add_library(${TARGET_NAME}_s STATIC ++add_library(${TARGET_NAME}_s STATIC EXCLUDE_FROM_ALL + $) + + set_ie_threading_interface_for(${TARGET_NAME}_s) +diff --git a/inference-engine/src/vpu/common/CMakeLists.txt b/inference-engine/src/vpu/common/CMakeLists.txt +index 249e47c28..4ddf63049 100644 +--- a/inference-engine/src/vpu/common/CMakeLists.txt ++++ b/inference-engine/src/vpu/common/CMakeLists.txt +@@ -5,7 +5,7 @@ + file(GLOB_RECURSE SOURCES *.cpp *.hpp *.h) + + function(add_common_target TARGET_NAME STATIC_IE) +- add_library(${TARGET_NAME} STATIC ${SOURCES}) ++ add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${SOURCES}) + + ie_faster_build(${TARGET_NAME} + UNITY +@@ -60,7 +60,7 @@ add_common_target("vpu_common_lib" FALSE) + + # Unit tests support for graph transformer + if(WIN32) +- add_common_target("vpu_common_lib_test_static" TRUE) ++ #add_common_target("vpu_common_lib_test_static" TRUE) + else() + add_library("vpu_common_lib_test_static" ALIAS "vpu_common_lib") + endif() +diff --git a/inference-engine/src/vpu/graph_transformer/CMakeLists.txt b/inference-engine/src/vpu/graph_transformer/CMakeLists.txt +index bc73ab5b1..b4c1547fc 100644 +--- a/inference-engine/src/vpu/graph_transformer/CMakeLists.txt ++++ b/inference-engine/src/vpu/graph_transformer/CMakeLists.txt +@@ -5,7 +5,7 @@ + file(GLOB_RECURSE SOURCES *.cpp *.hpp *.h *.inc) + + function(add_graph_transformer_target TARGET_NAME STATIC_IE) +- add_library(${TARGET_NAME} STATIC ${SOURCES}) ++ add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${SOURCES}) + + set_ie_threading_interface_for(${TARGET_NAME}) + +@@ -70,7 +70,7 @@ add_graph_transformer_target("vpu_graph_transformer" FALSE) + + # Unit tests support for graph transformer + if(WIN32) +- add_graph_transformer_target("vpu_graph_transformer_test_static" TRUE) ++ #add_graph_transformer_target("vpu_graph_transformer_test_static" TRUE) + else() + add_library("vpu_graph_transformer_test_static" ALIAS "vpu_graph_transformer") + endif() +diff --git a/inference-engine/thirdparty/pugixml/CMakeLists.txt b/inference-engine/thirdparty/pugixml/CMakeLists.txt +index 8bcb2801a..f7e031c01 100644 +--- a/inference-engine/thirdparty/pugixml/CMakeLists.txt ++++ b/inference-engine/thirdparty/pugixml/CMakeLists.txt +@@ -41,7 +41,7 @@ if(BUILD_SHARED_LIBS) + else() + add_library(pugixml STATIC ${SOURCES}) + if (MSVC) +- add_library(pugixml_mt STATIC ${SOURCES}) ++ #add_library(pugixml_mt STATIC ${SOURCES}) + #if (WIN32) + # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +diff --git a/ngraph/core/builder/CMakeLists.txt b/ngraph/core/builder/CMakeLists.txt +index ff5c381e7..2797ec9ab 100644 +--- a/ngraph/core/builder/CMakeLists.txt ++++ b/ngraph/core/builder/CMakeLists.txt +@@ -16,7 +16,7 @@ source_group("src" FILES ${LIBRARY_SRC}) + source_group("include" FILES ${PUBLIC_HEADERS}) + + # Create shared library +-add_library(${TARGET_NAME} STATIC ${LIBRARY_SRC} ${PUBLIC_HEADERS}) ++add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${LIBRARY_SRC} ${PUBLIC_HEADERS}) + + if(COMMAND ie_faster_build) + ie_faster_build(${TARGET_NAME} +diff --git a/ngraph/core/reference/CMakeLists.txt b/ngraph/core/reference/CMakeLists.txt +index ef4a764ab..f6d3172e2 100644 +--- a/ngraph/core/reference/CMakeLists.txt ++++ b/ngraph/core/reference/CMakeLists.txt +@@ -16,7 +16,7 @@ source_group("src" FILES ${LIBRARY_SRC}) + source_group("include" FILES ${PUBLIC_HEADERS}) + + # Create shared library +-add_library(${TARGET_NAME} STATIC ${LIBRARY_SRC} ${PUBLIC_HEADERS}) ++add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${LIBRARY_SRC} ${PUBLIC_HEADERS}) + + if(COMMAND ie_faster_build) + ie_faster_build(${TARGET_NAME} +diff --git a/openvino/itt/CMakeLists.txt b/openvino/itt/CMakeLists.txt +index e9f880b8c..c63f4df63 100644 +--- a/openvino/itt/CMakeLists.txt ++++ b/openvino/itt/CMakeLists.txt +@@ -6,7 +6,7 @@ set(TARGET_NAME itt) + + file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.hpp") + +-add_library(${TARGET_NAME} STATIC ${SOURCES}) ++add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${SOURCES}) + + add_library(openvino::itt ALIAS ${TARGET_NAME}) + diff --git a/platforms/winpack_dldt/2021.4/20210630-dldt-pdb.patch b/platforms/winpack_dldt/2021.4/20210630-dldt-pdb.patch new file mode 100644 index 000000000000..65e6f84dc80b --- /dev/null +++ b/platforms/winpack_dldt/2021.4/20210630-dldt-pdb.patch @@ -0,0 +1,15 @@ +iff --git a/CMakeLists.txt b/CMakeLists.txt +index e0706a72e..9a053b1e4 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -6,6 +6,10 @@ cmake_minimum_required(VERSION 3.13) + + project(OpenVINO) + ++set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /FS") ++set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") ++set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") ++ + set(OpenVINO_MAIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + set(IE_MAIN_SOURCE_DIR ${OpenVINO_MAIN_SOURCE_DIR}/inference-engine) + diff --git a/platforms/winpack_dldt/2021.4/20210630-dldt-vs-version.patch b/platforms/winpack_dldt/2021.4/20210630-dldt-vs-version.patch new file mode 100644 index 000000000000..36b0068775eb --- /dev/null +++ b/platforms/winpack_dldt/2021.4/20210630-dldt-vs-version.patch @@ -0,0 +1,16 @@ +diff --git a/cmake/developer_package/vs_version/vs_version.cmake b/cmake/developer_package/vs_version/vs_version.cmake +index 14d4c0e1e..6a44f73b9 100644 +--- a/cmake/developer_package/vs_version/vs_version.cmake ++++ b/cmake/developer_package/vs_version/vs_version.cmake +@@ -8,9 +8,9 @@ set(IE_VS_VER_FILEVERSION_STR "${IE_VERSION_MAJOR}.${IE_VERSION_MINOR}.${IE_VERS + + set(IE_VS_VER_COMPANY_NAME_STR "Intel Corporation") + set(IE_VS_VER_PRODUCTVERSION_STR "${CI_BUILD_NUMBER}") +-set(IE_VS_VER_PRODUCTNAME_STR "OpenVINO toolkit") ++set(IE_VS_VER_PRODUCTNAME_STR "OpenVINO toolkit (for OpenCV Windows package)") + set(IE_VS_VER_COPYRIGHT_STR "Copyright (C) 2018-2021, Intel Corporation") +-set(IE_VS_VER_COMMENTS_STR "https://docs.openvinotoolkit.org/") ++set(IE_VS_VER_COMMENTS_STR "https://github.com/opencv/opencv/wiki/Intel%27s-Deep-Learning-Inference-Engine-backend") + + # + # ie_add_vs_version_file(NAME diff --git a/platforms/winpack_dldt/2021.4/build.config.py b/platforms/winpack_dldt/2021.4/build.config.py new file mode 100644 index 000000000000..33ef1050cad4 --- /dev/null +++ b/platforms/winpack_dldt/2021.4/build.config.py @@ -0,0 +1 @@ +os.environ['CI_BUILD_NUMBER'] = '2021.4.0-opencv_winpack_dldt' diff --git a/platforms/winpack_dldt/2021.4/patch.config.py b/platforms/winpack_dldt/2021.4/patch.config.py new file mode 100644 index 000000000000..7f8715aae2da --- /dev/null +++ b/platforms/winpack_dldt/2021.4/patch.config.py @@ -0,0 +1,4 @@ +applyPatch('20210630-dldt-disable-unused-targets.patch') +applyPatch('20210630-dldt-pdb.patch') +applyPatch('20210630-dldt-disable-multidevice-autoplugin.patch') +applyPatch('20210630-dldt-vs-version.patch') diff --git a/platforms/winpack_dldt/2021.4/sysroot.config.py b/platforms/winpack_dldt/2021.4/sysroot.config.py new file mode 100644 index 000000000000..fa4281107d23 --- /dev/null +++ b/platforms/winpack_dldt/2021.4/sysroot.config.py @@ -0,0 +1,56 @@ +sysroot_bin_dir = prepare_dir(self.sysrootdir / 'bin') +copytree(self.build_dir / 'install', self.sysrootdir / 'ngraph') +#rm_one(self.sysrootdir / 'ngraph' / 'lib' / 'ngraph.dll') + +build_config = 'Release' if not self.config.build_debug else 'Debug' +build_bin_dir = self.build_dir / 'bin' / 'intel64' / build_config + +def copy_bin(name): + global build_bin_dir, sysroot_bin_dir + copytree(build_bin_dir / name, sysroot_bin_dir / name) + +dll_suffix = 'd' if self.config.build_debug else '' +def copy_dll(name): + global copy_bin, dll_suffix + copy_bin(name + dll_suffix + '.dll') + copy_bin(name + dll_suffix + '.pdb') + +copy_bin('cache.json') +copy_dll('clDNNPlugin') +copy_dll('HeteroPlugin') +copy_dll('inference_engine') +copy_dll('inference_engine_ir_reader') +#copy_dll('inference_engine_ir_v7_reader') +copy_dll('inference_engine_legacy') +copy_dll('inference_engine_transformations') # runtime +copy_dll('inference_engine_lp_transformations') # runtime +#copy_dll('inference_engine_preproc') # runtime +copy_dll('MKLDNNPlugin') # runtime +copy_dll('myriadPlugin') # runtime +#copy_dll('MultiDevicePlugin') # runtime, not used +copy_dll('ngraph') +copy_bin('plugins.xml') +copy_bin('pcie-ma2x8x.elf') +copy_bin('usb-ma2x8x.mvcmd') + +copytree(self.srcdir / 'inference-engine' / 'temp' / 'tbb' / 'bin', sysroot_bin_dir) +copytree(self.srcdir / 'inference-engine' / 'temp' / 'tbb', self.sysrootdir / 'tbb') + +sysroot_ie_dir = prepare_dir(self.sysrootdir / 'deployment_tools' / 'inference_engine') +sysroot_ie_lib_dir = prepare_dir(sysroot_ie_dir / 'lib' / 'intel64') + +copytree(self.srcdir / 'inference-engine' / 'include', sysroot_ie_dir / 'include') +if not self.config.build_debug: + copytree(build_bin_dir / 'ngraph.lib', sysroot_ie_lib_dir / 'ngraph.lib') + copytree(build_bin_dir / 'inference_engine.lib', sysroot_ie_lib_dir / 'inference_engine.lib') + copytree(build_bin_dir / 'inference_engine_ir_reader.lib', sysroot_ie_lib_dir / 'inference_engine_ir_reader.lib') + copytree(build_bin_dir / 'inference_engine_legacy.lib', sysroot_ie_lib_dir / 'inference_engine_legacy.lib') +else: + copytree(build_bin_dir / 'ngraphd.lib', sysroot_ie_lib_dir / 'ngraphd.lib') + copytree(build_bin_dir / 'inference_engined.lib', sysroot_ie_lib_dir / 'inference_engined.lib') + copytree(build_bin_dir / 'inference_engine_ir_readerd.lib', sysroot_ie_lib_dir / 'inference_engine_ir_readerd.lib') + copytree(build_bin_dir / 'inference_engine_legacyd.lib', sysroot_ie_lib_dir / 'inference_engine_legacyd.lib') + +sysroot_license_dir = prepare_dir(self.sysrootdir / 'etc' / 'licenses') +copytree(self.srcdir / 'LICENSE', sysroot_license_dir / 'dldt-LICENSE') +copytree(self.sysrootdir / 'tbb/LICENSE', sysroot_license_dir / 'tbb-LICENSE') diff --git a/platforms/winpack_dldt/build_package.py b/platforms/winpack_dldt/build_package.py index c3f835cac324..46926a38a512 100644 --- a/platforms/winpack_dldt/build_package.py +++ b/platforms/winpack_dldt/build_package.py @@ -214,7 +214,7 @@ def init_patchset(self): patch_hashsum = hashlib.md5(self.patch_file_contents.encode('utf-8')).hexdigest() except: log.warn("Can't compute hashsum of patches: %s", self.patch_file) - self.patch_hashsum = patch_hashsum + self.patch_hashsum = self.config.override_patch_hashsum if self.config.override_patch_hashsum else patch_hashsum def prepare_sources(self): @@ -355,7 +355,6 @@ def build(self, builderDLDT): BUILD_PERF_TESTS='OFF', ENABLE_CXX11='ON', WITH_INF_ENGINE='ON', - INF_ENGINE_RELEASE=str(self.config.dldt_release), WITH_TBB='ON', CPU_BASELINE='AVX2', CMAKE_INSTALL_PREFIX=str(self.install_dir), @@ -383,6 +382,9 @@ def build(self, builderDLDT): OPENCV_PYTHON_INSTALL_PATH='python', ) + if self.config.dldt_release: + cmake_vars['INF_ENGINE_RELEASE'] = str(self.config.dldt_release) + cmake_vars['INF_ENGINE_LIB_DIRS:PATH'] = str(builderDLDT.sysrootdir / 'deployment_tools/inference_engine/lib/intel64') assert os.path.exists(cmake_vars['INF_ENGINE_LIB_DIRS:PATH']), cmake_vars['INF_ENGINE_LIB_DIRS:PATH'] cmake_vars['INF_ENGINE_INCLUDE_DIRS:PATH'] = str(builderDLDT.sysrootdir / 'deployment_tools/inference_engine/include') @@ -466,8 +468,8 @@ def package_sources(self): def main(): dldt_src_url = 'https://github.com/openvinotoolkit/openvino' - dldt_src_commit = '2021.3' - dldt_release = '2021030000' + dldt_src_commit = '2021.4' + dldt_release = None build_cache_dir_default = os.environ.get('BUILD_CACHE_DIR', '.build_cache') build_subst_drive = os.environ.get('BUILD_SUBST_DRIVE', None) @@ -494,13 +496,15 @@ def main(): parser.add_argument('--dldt_src_branch', help='DLDT checkout branch') parser.add_argument('--dldt_src_commit', default=dldt_src_commit, help='DLDT source commit / tag (default: %s)' % dldt_src_commit) parser.add_argument('--dldt_src_git_clone_extra', action='append', help='DLDT git clone extra args') - parser.add_argument('--dldt_release', default=dldt_release, help='DLDT release code for INF_ENGINE_RELEASE (default: %s)' % dldt_release) + parser.add_argument('--dldt_release', default=dldt_release, help='DLDT release code for INF_ENGINE_RELEASE, e.g 2021030000 (default: %s)' % dldt_release) parser.add_argument('--dldt_reference_dir', help='DLDT reference git repository (optional)') parser.add_argument('--dldt_src_dir', help='DLDT custom source repository (skip git checkout and patching, use for TESTING only)') parser.add_argument('--dldt_config', help='Specify DLDT build configuration (defaults to evaluate from DLDT commit/branch)') + parser.add_argument('--override_patch_hashsum', default='', help='(script debug mode)') + args = parser.parse_args() log.basicConfig( diff --git a/samples/android/build.gradle.in b/samples/android/build.gradle.in index e89eb911be7d..934a1a69d0db 100644 --- a/samples/android/build.gradle.in +++ b/samples/android/build.gradle.in @@ -8,6 +8,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:@ANDROID_GRADLE_PLUGIN_VERSION@' + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:@KOTLIN_PLUGIN_VERSION@' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp b/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp index 5bcc878965a2..f9abbae94527 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp @@ -89,7 +89,7 @@ void MatchingMethod( int, void* ) //! [create_result_matrix] /// Create the result matrix - int result_cols = img.cols - templ.cols + 1; + int result_cols = img.cols - templ.cols + 1; int result_rows = img.rows - templ.rows + 1; result.create( result_rows, result_cols, CV_32FC1 ); diff --git a/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp b/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp index 61b6d607ceb6..bcb547a2fb9f 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp @@ -72,18 +72,18 @@ void Hist_and_Backproj(int, void* ) //! [initialize] int histSize = MAX( bins, 2 ); float hue_range[] = { 0, 180 }; - const float* ranges = { hue_range }; + const float* ranges[] = { hue_range }; //! [initialize] //! [Get the Histogram and normalize it] Mat hist; - calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false ); + calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, ranges, true, false ); normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() ); //! [Get the Histogram and normalize it] //! [Get Backprojection] Mat backproj; - calcBackProject( &hue, 1, 0, hist, backproj, &ranges, 1, true ); + calcBackProject( &hue, 1, 0, hist, backproj, ranges, 1, true ); //! [Get Backprojection] //! [Draw the backproj] diff --git a/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp b/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp index 86167e519a2f..a7582e42820a 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp @@ -37,7 +37,7 @@ int main(int argc, char** argv) //! [Set the ranges ( for B,G,R) )] float range[] = { 0, 256 }; //the upper boundary is exclusive - const float* histRange = { range }; + const float* histRange[] = { range }; //! [Set the ranges ( for B,G,R) )] //! [Set histogram param] @@ -46,9 +46,9 @@ int main(int argc, char** argv) //! [Compute the histograms] Mat b_hist, g_hist, r_hist; - calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); + calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, histRange, uniform, accumulate ); + calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, histRange, uniform, accumulate ); + calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, histRange, uniform, accumulate ); //! [Compute the histograms] //! [Draw the histograms for B, G and R] diff --git a/samples/dnn/CMakeLists.txt b/samples/dnn/CMakeLists.txt index f2cb949d0afe..209fbb586c43 100644 --- a/samples/dnn/CMakeLists.txt +++ b/samples/dnn/CMakeLists.txt @@ -4,6 +4,7 @@ set(OPENCV_DNN_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_dnn + opencv_video opencv_imgcodecs opencv_videoio opencv_highgui) diff --git a/samples/dnn/classification.cpp b/samples/dnn/classification.cpp index 8440371688bc..769d6874bed4 100644 --- a/samples/dnn/classification.cpp +++ b/samples/dnn/classification.cpp @@ -22,12 +22,17 @@ std::string keys = "0: automatically (by default), " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "3: OpenCV implementation }" + "3: OpenCV implementation, " + "4: VKCOM, " + "5: CUDA }," "{ target | 0 | Choose one of target computation devices: " "0: CPU target (by default), " "1: OpenCL, " "2: OpenCL fp16 (half-float precision), " - "3: VPU }"; + "3: VPU, " + "4: Vulkan, " + "6: CUDA, " + "7: CUDA fp16 (half-float preprocess) }"; using namespace cv; using namespace dnn; diff --git a/samples/dnn/classification.py b/samples/dnn/classification.py index 558c8b0bdce4..be639e8d743d 100644 --- a/samples/dnn/classification.py +++ b/samples/dnn/classification.py @@ -7,9 +7,9 @@ def get_args_parser(func_args): backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, - cv.dnn.DNN_BACKEND_OPENCV) + cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, - cv.dnn.DNN_TARGET_HDDL) + cv.dnn.DNN_TARGET_HDDL, cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--zoo', default=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models.yml'), @@ -32,14 +32,19 @@ def get_args_parser(func_args): "%d: automatically (by default), " "%d: Halide language (http://halide-lang.org/), " "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "%d: OpenCV implementation" % backends) + "%d: OpenCV implementation, " + "%d: VKCOM, " + "%d: CUDA" % backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Choose one of target computation devices: ' '%d: CPU target (by default), ' '%d: OpenCL, ' '%d: OpenCL fp16 (half-float precision), ' '%d: NCS2 VPU, ' - '%d: HDDL VPU' % targets) + '%d: HDDL VPU, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA fp16 (half-float preprocess)'% targets) args, _ = parser.parse_known_args() add_preproc_args(args.zoo, parser, 'classification') diff --git a/samples/dnn/dasiamrpn_tracker.cpp b/samples/dnn/dasiamrpn_tracker.cpp index 0008cee25557..f6e307c682f7 100644 --- a/samples/dnn/dasiamrpn_tracker.cpp +++ b/samples/dnn/dasiamrpn_tracker.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace cv; using namespace cv::dnn; @@ -26,67 +27,19 @@ const char *keys = "0: automatically (by default), " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "3: OpenCV implementation }" + "3: OpenCV implementation, " + "4: VKCOM, " + "5: CUDA }," "{ target | 0 | Choose one of target computation devices: " "0: CPU target (by default), " "1: OpenCL, " "2: OpenCL fp16 (half-float precision), " - "3: VPU }" + "3: VPU, " + "4: Vulkan, " + "6: CUDA, " + "7: CUDA fp16 (half-float preprocess) }" ; -// Initial parameters of the model -struct trackerConfig -{ - float windowInfluence = 0.43f; - float lr = 0.4f; - int scale = 8; - bool swapRB = false; - int totalStride = 8; - float penaltyK = 0.055f; - int exemplarSize = 127; - int instanceSize = 271; - float contextAmount = 0.5f; - std::vector ratios = { 0.33f, 0.5f, 1.0f, 2.0f, 3.0f }; - int anchorNum = int(ratios.size()); - Mat anchors; - Mat windows; - Scalar avgChans; - Size imgSize = { 0, 0 }; - Rect2f targetBox = { 0, 0, 0, 0 }; - int scoreSize = (instanceSize - exemplarSize) / totalStride + 1; - - void update_scoreSize() - { - scoreSize = int((instanceSize - exemplarSize) / totalStride + 1); - } -}; - -static void softmax(const Mat& src, Mat& dst); -static void elementMax(Mat& src); -static Mat generateHanningWindow(const trackerConfig& trackState); -static Mat generateAnchors(trackerConfig& trackState); -static Mat getSubwindow(Mat& img, const Rect2f& targetBox, float originalSize, Scalar avgChans); -static float trackerEval(Mat img, trackerConfig& trackState, Net& siamRPN); -static void trackerInit(Mat img, trackerConfig& trackState, Net& siamRPN, Net& siamKernelR1, Net& siamKernelCL1); - -template static -T sizeCal(const T& w, const T& h) -{ - T pad = (w + h) * T(0.5); - T sz2 = (w + pad) * (h + pad); - return sqrt(sz2); -} - -template <> -Mat sizeCal(const Mat& w, const Mat& h) -{ - Mat pad = (w + h) * 0.5; - Mat sz2 = (w + pad).mul((h + pad)); - - cv::sqrt(sz2, sz2); - return sz2; -} - static int run(int argc, char** argv) { @@ -106,13 +59,16 @@ int run(int argc, char** argv) int backend = parser.get("backend"); int target = parser.get("target"); - // Read nets. - Net siamRPN, siamKernelCL1, siamKernelR1; + Ptr tracker; try { - siamRPN = readNet(samples::findFile(net)); - siamKernelCL1 = readNet(samples::findFile(kernel_cls1)); - siamKernelR1 = readNet(samples::findFile(kernel_r1)); + TrackerDaSiamRPN::Params params; + params.model = samples::findFile(net); + params.kernel_cls1 = samples::findFile(kernel_cls1); + params.kernel_r1 = samples::findFile(kernel_r1); + params.backend = backend; + params.target = target; + tracker = TrackerDaSiamRPN::create(params); } catch (const cv::Exception& ee) { @@ -124,14 +80,6 @@ int run(int argc, char** argv) return 2; } - // Set model backend. - siamRPN.setPreferableBackend(backend); - siamRPN.setPreferableTarget(target); - siamKernelR1.setPreferableBackend(backend); - siamKernelR1.setPreferableTarget(target); - siamKernelCL1.setPreferableBackend(backend); - siamKernelCL1.setPreferableTarget(target); - const std::string winName = "DaSiamRPN"; namedWindow(winName, WINDOW_AUTOSIZE); @@ -174,17 +122,7 @@ int run(int argc, char** argv) Rect selectRect = selectROI(winName, image_select); std::cout << "ROI=" << selectRect << std::endl; - trackerConfig trackState; - trackState.update_scoreSize(); - trackState.targetBox = Rect2f( - float(selectRect.x) + float(selectRect.width) * 0.5f, // FIXIT don't use center in Rect structures, it is confusing - float(selectRect.y) + float(selectRect.height) * 0.5f, - float(selectRect.width), - float(selectRect.height) - ); - - // Set tracking template. - trackerInit(image, trackState, siamRPN, siamKernelR1, siamKernelCL1); + tracker->init(image, selectRect); TickMeter tickMeter; @@ -197,16 +135,14 @@ int run(int argc, char** argv) break; } + Rect rect; + tickMeter.start(); - float score = trackerEval(image, trackState, siamRPN); + bool ok = tracker->update(image, rect); tickMeter.stop(); - Rect rect = { - int(trackState.targetBox.x - int(trackState.targetBox.width / 2)), - int(trackState.targetBox.y - int(trackState.targetBox.height / 2)), - int(trackState.targetBox.width), - int(trackState.targetBox.height) - }; + float score = tracker->getTrackingScore(); + std::cout << "frame " << count << ": predicted score=" << score << " rect=" << rect << @@ -214,12 +150,16 @@ int run(int argc, char** argv) std::endl; Mat render_image = image.clone(); - rectangle(render_image, rect, Scalar(0, 255, 0), 2); - std::string timeLabel = format("Inference time: %.2f ms", tickMeter.getTimeMilli()); - std::string scoreLabel = format("Score: %f", score); - putText(render_image, timeLabel, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); - putText(render_image, scoreLabel, Point(0, 35), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); + if (ok) + { + rectangle(render_image, rect, Scalar(0, 255, 0), 2); + + std::string timeLabel = format("Inference time: %.2f ms", tickMeter.getTimeMilli()); + std::string scoreLabel = format("Score: %f", score); + putText(render_image, timeLabel, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); + putText(render_image, scoreLabel, Point(0, 35), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); + } imshow(winName, render_image); @@ -234,275 +174,6 @@ int run(int argc, char** argv) return 0; } -Mat generateHanningWindow(const trackerConfig& trackState) -{ - Mat baseWindows, HanningWindows; - - createHanningWindow(baseWindows, Size(trackState.scoreSize, trackState.scoreSize), CV_32F); - baseWindows = baseWindows.reshape(0, { 1, trackState.scoreSize, trackState.scoreSize }); - HanningWindows = baseWindows.clone(); - for (int i = 1; i < trackState.anchorNum; i++) - { - HanningWindows.push_back(baseWindows); - } - - return HanningWindows; -} - -Mat generateAnchors(trackerConfig& trackState) -{ - int totalStride = trackState.totalStride, scales = trackState.scale, scoreSize = trackState.scoreSize; - std::vector ratios = trackState.ratios; - std::vector baseAnchors; - int anchorNum = int(ratios.size()); - int size = totalStride * totalStride; - - float ori = -(float(scoreSize / 2)) * float(totalStride); - - for (auto i = 0; i < anchorNum; i++) - { - int ws = int(sqrt(size / ratios[i])); - int hs = int(ws * ratios[i]); - - float wws = float(ws) * scales; - float hhs = float(hs) * scales; - Rect2f anchor = { 0, 0, wws, hhs }; - baseAnchors.push_back(anchor); - } - - int anchorIndex[] = { 0, 0, 0, 0 }; - const int sizes[] = { 4, (int)ratios.size(), scoreSize, scoreSize }; - Mat anchors(4, sizes, CV_32F); - - for (auto i = 0; i < scoreSize; i++) - { - for (auto j = 0; j < scoreSize; j++) - { - for (auto k = 0; k < anchorNum; k++) - { - anchorIndex[0] = 1, anchorIndex[1] = k, anchorIndex[2] = i, anchorIndex[3] = j; - anchors.at(anchorIndex) = ori + totalStride * i; - - anchorIndex[0] = 0; - anchors.at(anchorIndex) = ori + totalStride * j; - - anchorIndex[0] = 2; - anchors.at(anchorIndex) = baseAnchors[k].width; - - anchorIndex[0] = 3; - anchors.at(anchorIndex) = baseAnchors[k].height; - } - } - } - - return anchors; -} - -Mat getSubwindow(Mat& img, const Rect2f& targetBox, float originalSize, Scalar avgChans) -{ - Mat zCrop, dst; - Size imgSize = img.size(); - float c = (originalSize + 1) / 2; - float xMin = (float)cvRound(targetBox.x - c); - float xMax = xMin + originalSize - 1; - float yMin = (float)cvRound(targetBox.y - c); - float yMax = yMin + originalSize - 1; - - int leftPad = (int)(fmax(0., -xMin)); - int topPad = (int)(fmax(0., -yMin)); - int rightPad = (int)(fmax(0., xMax - imgSize.width + 1)); - int bottomPad = (int)(fmax(0., yMax - imgSize.height + 1)); - - xMin = xMin + leftPad; - xMax = xMax + leftPad; - yMax = yMax + topPad; - yMin = yMin + topPad; - - if (topPad == 0 && bottomPad == 0 && leftPad == 0 && rightPad == 0) - { - img(Rect(int(xMin), int(yMin), int(xMax - xMin + 1), int(yMax - yMin + 1))).copyTo(zCrop); - } - else - { - copyMakeBorder(img, dst, topPad, bottomPad, leftPad, rightPad, BORDER_CONSTANT, avgChans); - dst(Rect(int(xMin), int(yMin), int(xMax - xMin + 1), int(yMax - yMin + 1))).copyTo(zCrop); - } - - return zCrop; -} - -void softmax(const Mat& src, Mat& dst) -{ - Mat maxVal; - cv::max(src.row(1), src.row(0), maxVal); - - src.row(1) -= maxVal; - src.row(0) -= maxVal; - - exp(src, dst); - - Mat sumVal = dst.row(0) + dst.row(1); - dst.row(0) = dst.row(0) / sumVal; - dst.row(1) = dst.row(1) / sumVal; -} - -void elementMax(Mat& src) -{ - int* p = src.size.p; - int index[] = { 0, 0, 0, 0 }; - for (int n = 0; n < *p; n++) - { - for (int k = 0; k < *(p + 1); k++) - { - for (int i = 0; i < *(p + 2); i++) - { - for (int j = 0; j < *(p + 3); j++) - { - index[0] = n, index[1] = k, index[2] = i, index[3] = j; - float& v = src.at(index); - v = fmax(v, 1.0f / v); - } - } - } - } -} - -float trackerEval(Mat img, trackerConfig& trackState, Net& siamRPN) -{ - Rect2f targetBox = trackState.targetBox; - - float wc = targetBox.height + trackState.contextAmount * (targetBox.width + targetBox.height); - float hc = targetBox.width + trackState.contextAmount * (targetBox.width + targetBox.height); - - float sz = sqrt(wc * hc); - float scaleZ = trackState.exemplarSize / sz; - - float searchSize = float((trackState.instanceSize - trackState.exemplarSize) / 2); - float pad = searchSize / scaleZ; - float sx = sz + 2 * pad; - - Mat xCrop = getSubwindow(img, targetBox, (float)cvRound(sx), trackState.avgChans); - - static Mat blob; - std::vector outs; - std::vector outNames; - Mat delta, score; - Mat sc, rc, penalty, pscore; - - blobFromImage(xCrop, blob, 1.0, Size(trackState.instanceSize, trackState.instanceSize), Scalar(), trackState.swapRB, false, CV_32F); - - siamRPN.setInput(blob); - - outNames = siamRPN.getUnconnectedOutLayersNames(); - siamRPN.forward(outs, outNames); - - delta = outs[0]; - score = outs[1]; - - score = score.reshape(0, { 2, trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); - delta = delta.reshape(0, { 4, trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); - - softmax(score, score); - - targetBox.width *= scaleZ; - targetBox.height *= scaleZ; - - score = score.row(1); - score = score.reshape(0, { 5, 19, 19 }); - - // Post processing - delta.row(0) = delta.row(0).mul(trackState.anchors.row(2)) + trackState.anchors.row(0); - delta.row(1) = delta.row(1).mul(trackState.anchors.row(3)) + trackState.anchors.row(1); - exp(delta.row(2), delta.row(2)); - delta.row(2) = delta.row(2).mul(trackState.anchors.row(2)); - exp(delta.row(3), delta.row(3)); - delta.row(3) = delta.row(3).mul(trackState.anchors.row(3)); - - sc = sizeCal(delta.row(2), delta.row(3)) / sizeCal(targetBox.width, targetBox.height); - elementMax(sc); - - rc = delta.row(2).mul(1 / delta.row(3)); - rc = (targetBox.width / targetBox.height) / rc; - elementMax(rc); - - // Calculating the penalty - exp(((rc.mul(sc) - 1.) * trackState.penaltyK * (-1.0)), penalty); - penalty = penalty.reshape(0, { trackState.anchorNum, trackState.scoreSize, trackState.scoreSize }); - - pscore = penalty.mul(score); - pscore = pscore * (1.0 - trackState.windowInfluence) + trackState.windows * trackState.windowInfluence; - - int bestID[] = { 0 }; - // Find the index of best score. - minMaxIdx(pscore.reshape(0, { trackState.anchorNum * trackState.scoreSize * trackState.scoreSize, 1 }), 0, 0, 0, bestID); - delta = delta.reshape(0, { 4, trackState.anchorNum * trackState.scoreSize * trackState.scoreSize }); - penalty = penalty.reshape(0, { trackState.anchorNum * trackState.scoreSize * trackState.scoreSize, 1 }); - score = score.reshape(0, { trackState.anchorNum * trackState.scoreSize * trackState.scoreSize, 1 }); - - int index[] = { 0, bestID[0] }; - Rect2f resBox = { 0, 0, 0, 0 }; - - resBox.x = delta.at(index) / scaleZ; - index[0] = 1; - resBox.y = delta.at(index) / scaleZ; - index[0] = 2; - resBox.width = delta.at(index) / scaleZ; - index[0] = 3; - resBox.height = delta.at(index) / scaleZ; - - float lr = penalty.at(bestID) * score.at(bestID) * trackState.lr; - - resBox.x = resBox.x + targetBox.x; - resBox.y = resBox.y + targetBox.y; - targetBox.width /= scaleZ; - targetBox.height /= scaleZ; - - resBox.width = targetBox.width * (1 - lr) + resBox.width * lr; - resBox.height = targetBox.height * (1 - lr) + resBox.height * lr; - - resBox.x = float(fmax(0., fmin(float(trackState.imgSize.width), resBox.x))); - resBox.y = float(fmax(0., fmin(float(trackState.imgSize.height), resBox.y))); - resBox.width = float(fmax(10., fmin(float(trackState.imgSize.width), resBox.width))); - resBox.height = float(fmax(10., fmin(float(trackState.imgSize.height), resBox.height))); - - trackState.targetBox = resBox; - return score.at(bestID); -} - -void trackerInit(Mat img, trackerConfig& trackState, Net& siamRPN, Net& siamKernelR1, Net& siamKernelCL1) -{ - Rect2f targetBox = trackState.targetBox; - Mat anchors = generateAnchors(trackState); - trackState.anchors = anchors; - - Mat windows = generateHanningWindow(trackState); - - trackState.windows = windows; - trackState.imgSize = img.size(); - - trackState.avgChans = mean(img); - float wc = targetBox.width + trackState.contextAmount * (targetBox.width + targetBox.height); - float hc = targetBox.height + trackState.contextAmount * (targetBox.width + targetBox.height); - float sz = (float)cvRound(sqrt(wc * hc)); - - Mat zCrop = getSubwindow(img, targetBox, sz, trackState.avgChans); - static Mat blob; - - blobFromImage(zCrop, blob, 1.0, Size(trackState.exemplarSize, trackState.exemplarSize), Scalar(), trackState.swapRB, false, CV_32F); - siamRPN.setInput(blob); - Mat out1; - siamRPN.forward(out1, "63"); - - siamKernelCL1.setInput(out1); - siamKernelR1.setInput(out1); - - Mat cls1 = siamKernelCL1.forward(); - Mat r1 = siamKernelR1.forward(); - std::vector r1_shape = { 20, 256, 4, 4 }, cls1_shape = { 10, 256, 4, 4 }; - - siamRPN.setParam(siamRPN.getLayerId("65"), 0, r1.reshape(0, r1_shape)); - siamRPN.setParam(siamRPN.getLayerId("68"), 0, cls1.reshape(0, cls1_shape)); -} int main(int argc, char **argv) { diff --git a/samples/dnn/dasiamrpn_tracker.py b/samples/dnn/dasiamrpn_tracker.py deleted file mode 100644 index 03e99d6dbffa..000000000000 --- a/samples/dnn/dasiamrpn_tracker.py +++ /dev/null @@ -1,291 +0,0 @@ -""" -DaSiamRPN tracker. -Original paper: https://arxiv.org/abs/1808.06048 -Link to original repo: https://github.com/foolwood/DaSiamRPN -Links to onnx models: -network: https://www.dropbox.com/s/rr1lk9355vzolqv/dasiamrpn_model.onnx?dl=0 -kernel_r1: https://www.dropbox.com/s/999cqx5zrfi7w4p/dasiamrpn_kernel_r1.onnx?dl=0 -kernel_cls1: https://www.dropbox.com/s/qvmtszx5h339a0w/dasiamrpn_kernel_cls1.onnx?dl=0 -""" - -import numpy as np -import cv2 as cv -import argparse -import sys - -class DaSiamRPNTracker: - # Initialization of used values, initial bounding box, used network - def __init__(self, net="dasiamrpn_model.onnx", kernel_r1="dasiamrpn_kernel_r1.onnx", kernel_cls1="dasiamrpn_kernel_cls1.onnx"): - self.windowing = "cosine" - self.exemplar_size = 127 - self.instance_size = 271 - self.total_stride = 8 - self.score_size = (self.instance_size - self.exemplar_size) // self.total_stride + 1 - self.context_amount = 0.5 - self.ratios = [0.33, 0.5, 1, 2, 3] - self.scales = [8, ] - self.anchor_num = len(self.ratios) * len(self.scales) - self.penalty_k = 0.055 - self.window_influence = 0.42 - self.lr = 0.295 - self.score = [] - if self.windowing == "cosine": - self.window = np.outer(np.hanning(self.score_size), np.hanning(self.score_size)) - elif self.windowing == "uniform": - self.window = np.ones((self.score_size, self.score_size)) - self.window = np.tile(self.window.flatten(), self.anchor_num) - # Loading network`s and kernel`s models - self.net = cv.dnn.readNet(net) - self.kernel_r1 = cv.dnn.readNet(kernel_r1) - self.kernel_cls1 = cv.dnn.readNet(kernel_cls1) - - def init(self, im, init_bb): - target_pos, target_sz = np.array([init_bb[0], init_bb[1]]), np.array([init_bb[2], init_bb[3]]) - self.im_h = im.shape[0] - self.im_w = im.shape[1] - self.target_pos = target_pos - self.target_sz = target_sz - self.avg_chans = np.mean(im, axis=(0, 1)) - - # When we trying to generate ONNX model from the pre-trained .pth model - # we are using only one state of the network. In our case used state - # with big bounding box, so we were forced to add assertion for - # too small bounding boxes - current state of the network can not - # work properly with such small bounding boxes - if ((self.target_sz[0] * self.target_sz[1]) / float(self.im_h * self.im_w)) < 0.004: - raise AssertionError( - "Initializing BB is too small-try to restart tracker with larger BB") - - self.anchor = self.__generate_anchor() - wc_z = self.target_sz[0] + self.context_amount * sum(self.target_sz) - hc_z = self.target_sz[1] + self.context_amount * sum(self.target_sz) - s_z = round(np.sqrt(wc_z * hc_z)) - z_crop = self.__get_subwindow_tracking(im, self.exemplar_size, s_z) - z_crop = z_crop.transpose(2, 0, 1).reshape(1, 3, 127, 127).astype(np.float32) - self.net.setInput(z_crop) - z_f = self.net.forward('63') - self.kernel_r1.setInput(z_f) - r1 = self.kernel_r1.forward() - self.kernel_cls1.setInput(z_f) - cls1 = self.kernel_cls1.forward() - r1 = r1.reshape(20, 256, 4, 4) - cls1 = cls1.reshape(10, 256 , 4, 4) - self.net.setParam(self.net.getLayerId('65'), 0, r1) - self.net.setParam(self.net.getLayerId('68'), 0, cls1) - - # Сreating anchor for tracking bounding box - def __generate_anchor(self): - self.anchor = np.zeros((self.anchor_num, 4), dtype = np.float32) - size = self.total_stride * self.total_stride - count = 0 - - for ratio in self.ratios: - ws = int(np.sqrt(size / ratio)) - hs = int(ws * ratio) - for scale in self.scales: - wws = ws * scale - hhs = hs * scale - self.anchor[count] = [0, 0, wws, hhs] - count += 1 - - score_sz = int(self.score_size) - self.anchor = np.tile(self.anchor, score_sz * score_sz).reshape((-1, 4)) - ori = - (score_sz / 2) * self.total_stride - xx, yy = np.meshgrid([ori + self.total_stride * dx for dx in range(score_sz)], [ori + self.total_stride * dy for dy in range(score_sz)]) - xx, yy = np.tile(xx.flatten(), (self.anchor_num, 1)).flatten(), np.tile(yy.flatten(), (self.anchor_num, 1)).flatten() - self.anchor[:, 0], self.anchor[:, 1] = xx.astype(np.float32), yy.astype(np.float32) - return self.anchor - - # Function for updating tracker state - def update(self, im): - wc_z = self.target_sz[1] + self.context_amount * sum(self.target_sz) - hc_z = self.target_sz[0] + self.context_amount * sum(self.target_sz) - s_z = np.sqrt(wc_z * hc_z) - scale_z = self.exemplar_size / s_z - d_search = (self.instance_size - self.exemplar_size) / 2 - pad = d_search / scale_z - s_x = round(s_z + 2 * pad) - - # Region preprocessing part - x_crop = self.__get_subwindow_tracking(im, self.instance_size, s_x) - x_crop = x_crop.transpose(2, 0, 1).reshape(1, 3, 271, 271).astype(np.float32) - self.score = self.__tracker_eval(x_crop, scale_z) - self.target_pos[0] = max(0, min(self.im_w, self.target_pos[0])) - self.target_pos[1] = max(0, min(self.im_h, self.target_pos[1])) - self.target_sz[0] = max(10, min(self.im_w, self.target_sz[0])) - self.target_sz[1] = max(10, min(self.im_h, self.target_sz[1])) - - cx, cy = self.target_pos - w, h = self.target_sz - updated_bb = (cx, cy, w, h) - return True, updated_bb - - # Function for updating position of the bounding box - def __tracker_eval(self, x_crop, scale_z): - target_size = self.target_sz * scale_z - self.net.setInput(x_crop) - outNames = self.net.getUnconnectedOutLayersNames() - outNames = ['66', '68'] - delta, score = self.net.forward(outNames) - delta = np.transpose(delta, (1, 2, 3, 0)) - delta = np.ascontiguousarray(delta, dtype = np.float32) - delta = np.reshape(delta, (4, -1)) - score = np.transpose(score, (1, 2, 3, 0)) - score = np.ascontiguousarray(score, dtype = np.float32) - score = np.reshape(score, (2, -1)) - score = self.__softmax(score)[1, :] - delta[0, :] = delta[0, :] * self.anchor[:, 2] + self.anchor[:, 0] - delta[1, :] = delta[1, :] * self.anchor[:, 3] + self.anchor[:, 1] - delta[2, :] = np.exp(delta[2, :]) * self.anchor[:, 2] - delta[3, :] = np.exp(delta[3, :]) * self.anchor[:, 3] - - def __change(r): - return np.maximum(r, 1./r) - - def __sz(w, h): - pad = (w + h) * 0.5 - sz2 = (w + pad) * (h + pad) - return np.sqrt(sz2) - - def __sz_wh(wh): - pad = (wh[0] + wh[1]) * 0.5 - sz2 = (wh[0] + pad) * (wh[1] + pad) - return np.sqrt(sz2) - - s_c = __change(__sz(delta[2, :], delta[3, :]) / (__sz_wh(target_size))) - r_c = __change((target_size[0] / target_size[1]) / (delta[2, :] / delta[3, :])) - penalty = np.exp(-(r_c * s_c - 1.) * self.penalty_k) - pscore = penalty * score - pscore = pscore * (1 - self.window_influence) + self.window * self.window_influence - best_pscore_id = np.argmax(pscore) - target = delta[:, best_pscore_id] / scale_z - target_size /= scale_z - lr = penalty[best_pscore_id] * score[best_pscore_id] * self.lr - res_x = target[0] + self.target_pos[0] - res_y = target[1] + self.target_pos[1] - res_w = target_size[0] * (1 - lr) + target[2] * lr - res_h = target_size[1] * (1 - lr) + target[3] * lr - self.target_pos = np.array([res_x, res_y]) - self.target_sz = np.array([res_w, res_h]) - return score[best_pscore_id] - - def __softmax(self, x): - x_max = x.max(0) - e_x = np.exp(x - x_max) - y = e_x / e_x.sum(axis = 0) - return y - - # Reshaping cropped image for using in the model - def __get_subwindow_tracking(self, im, model_size, original_sz): - im_sz = im.shape - c = (original_sz + 1) / 2 - context_xmin = round(self.target_pos[0] - c) - context_xmax = context_xmin + original_sz - 1 - context_ymin = round(self.target_pos[1] - c) - context_ymax = context_ymin + original_sz - 1 - left_pad = int(max(0., -context_xmin)) - top_pad = int(max(0., -context_ymin)) - right_pad = int(max(0., context_xmax - im_sz[1] + 1)) - bot_pad = int(max(0., context_ymax - im_sz[0] + 1)) - context_xmin += left_pad - context_xmax += left_pad - context_ymin += top_pad - context_ymax += top_pad - r, c, k = im.shape - - if any([top_pad, bot_pad, left_pad, right_pad]): - te_im = np.zeros(( - r + top_pad + bot_pad, c + left_pad + right_pad, k), np.uint8) - te_im[top_pad:top_pad + r, left_pad:left_pad + c, :] = im - if top_pad: - te_im[0:top_pad, left_pad:left_pad + c, :] = self.avg_chans - if bot_pad: - te_im[r + top_pad:, left_pad:left_pad + c, :] = self.avg_chans - if left_pad: - te_im[:, 0:left_pad, :] = self.avg_chans - if right_pad: - te_im[:, c + left_pad:, :] = self.avg_chans - im_patch_original = te_im[int(context_ymin):int(context_ymax + 1), int(context_xmin):int(context_xmax + 1), :] - else: - im_patch_original = im[int(context_ymin):int(context_ymax + 1), int(context_xmin):int(context_xmax + 1), :] - - if not np.array_equal(model_size, original_sz): - im_patch_original = cv.resize(im_patch_original, (model_size, model_size)) - return im_patch_original - -# Sample for using DaSiamRPN tracker -def main(): - parser = argparse.ArgumentParser(description="Run tracker") - parser.add_argument("--input", type=str, help="Full path to input (empty for camera)") - parser.add_argument("--net", type=str, default="dasiamrpn_model.onnx", help="Full path to onnx model of net") - parser.add_argument("--kernel_r1", type=str, default="dasiamrpn_kernel_r1.onnx", help="Full path to onnx model of kernel_r1") - parser.add_argument("--kernel_cls1", type=str, default="dasiamrpn_kernel_cls1.onnx", help="Full path to onnx model of kernel_cls1") - args = parser.parse_args() - point1 = () - point2 = () - mark = True - drawing = False - cx, cy, w, h = 0.0, 0.0, 0, 0 - # Fucntion for drawing during videostream - def get_bb(event, x, y, flag, param): - nonlocal point1, point2, cx, cy, w, h, drawing, mark - - if event == cv.EVENT_LBUTTONDOWN: - if not drawing: - drawing = True - point1 = (x, y) - else: - drawing = False - - elif event == cv.EVENT_MOUSEMOVE: - if drawing: - point2 = (x, y) - - elif event == cv.EVENT_LBUTTONUP: - cx = point1[0] - (point1[0] - point2[0]) / 2 - cy = point1[1] - (point1[1] - point2[1]) / 2 - w = abs(point1[0] - point2[0]) - h = abs(point1[1] - point2[1]) - mark = False - - # Creating window for visualization - cap = cv.VideoCapture(args.input if args.input else 0) - cv.namedWindow("DaSiamRPN") - cv.setMouseCallback("DaSiamRPN", get_bb) - - whitespace_key = 32 - while cv.waitKey(40) != whitespace_key: - has_frame, frame = cap.read() - if not has_frame: - sys.exit(0) - cv.imshow("DaSiamRPN", frame) - - while mark: - twin = np.copy(frame) - if point1 and point2: - cv.rectangle(twin, point1, point2, (0, 255, 255), 3) - cv.imshow("DaSiamRPN", twin) - cv.waitKey(40) - - init_bb = (cx, cy, w, h) - tracker = DaSiamRPNTracker(args.net, args.kernel_r1, args.kernel_cls1) - tracker.init(frame, init_bb) - - # Tracking loop - while cap.isOpened(): - has_frame, frame = cap.read() - if not has_frame: - sys.exit(0) - _, new_bb = tracker.update(frame) - cx, cy, w, h = new_bb - cv.rectangle(frame, (int(cx - w // 2), int(cy - h // 2)), (int(cx - w // 2) + int(w), int(cy - h // 2) + int(h)),(0, 255, 255), 3) - cv.imshow("DaSiamRPN", frame) - key = cv.waitKey(1) - if key == ord("q"): - break - - cap.release() - cv.destroyAllWindows() - -if __name__ == "__main__": - main() diff --git a/samples/dnn/human_parsing.cpp b/samples/dnn/human_parsing.cpp index bf2cc294c8d3..0c00c0284135 100644 --- a/samples/dnn/human_parsing.cpp +++ b/samples/dnn/human_parsing.cpp @@ -78,12 +78,17 @@ int main(int argc, char**argv) "0: automatically (by default), " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "3: OpenCV implementation }" + "3: OpenCV implementation, " + "4: VKCOM, " + "5: CUDA }" "{target t | 0 | Choose one of target computation devices: " "0: CPU target (by default), " "1: OpenCL, " "2: OpenCL fp16 (half-float precision), " - "3: VPU }" + "3: VPU, " + "4: Vulkan, " + "6: CUDA, " + "7: CUDA fp16 (half-float preprocess) }" ); if (argc == 1 || parser.has("help")) { diff --git a/samples/dnn/human_parsing.py b/samples/dnn/human_parsing.py index 09371fe4a9c6..237f764b95cd 100644 --- a/samples/dnn/human_parsing.py +++ b/samples/dnn/human_parsing.py @@ -45,8 +45,10 @@ import cv2 as cv -backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV) -targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL) +backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV, + cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) +targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, + cv.dnn.DNN_TARGET_HDDL, cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) def preprocess(image): @@ -162,14 +164,19 @@ def parse_human(image, model_path, backend=cv.dnn.DNN_BACKEND_OPENCV, target=cv. help="Choose one of computation backends: " "%d: automatically (by default), " "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "%d: OpenCV implementation" % backends) + "%d: OpenCV implementation, " + "%d: VKCOM, " + "%d: CUDA"% backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Choose one of target computation devices: ' '%d: CPU target (by default), ' '%d: OpenCL, ' '%d: OpenCL fp16 (half-float precision), ' '%d: NCS2 VPU, ' - '%d: HDDL VPU' % targets) + '%d: HDDL VPU, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA fp16 (half-float preprocess)' % targets) args, _ = parser.parse_known_args() if not os.path.isfile(args.model): diff --git a/samples/dnn/object_detection.cpp b/samples/dnn/object_detection.cpp index 796e729ece90..5ff112fe5d13 100644 --- a/samples/dnn/object_detection.cpp +++ b/samples/dnn/object_detection.cpp @@ -27,12 +27,17 @@ std::string keys = "0: automatically (by default), " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "3: OpenCV implementation }" + "3: OpenCV implementation, " + "4: VKCOM, " + "5: CUDA }" "{ target | 0 | Choose one of target computation devices: " "0: CPU target (by default), " "1: OpenCL, " "2: OpenCL fp16 (half-float precision), " - "3: VPU }" + "3: VPU, " + "4: Vulkan, " + "6: CUDA, " + "7: CUDA fp16 (half-float preprocess) }" "{ async | 0 | Number of asynchronous forwards at the same time. " "Choose 0 for synchronous mode }"; diff --git a/samples/dnn/object_detection.py b/samples/dnn/object_detection.py index ec8bf82866b4..0ca55861596d 100644 --- a/samples/dnn/object_detection.py +++ b/samples/dnn/object_detection.py @@ -14,8 +14,10 @@ from tf_text_graph_ssd import createSSDGraph from tf_text_graph_faster_rcnn import createFasterRCNNGraph -backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV) -targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL) +backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV, + cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) +targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL, + cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--zoo', default=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models.yml'), @@ -35,14 +37,19 @@ "%d: automatically (by default), " "%d: Halide language (http://halide-lang.org/), " "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "%d: OpenCV implementation" % backends) + "%d: OpenCV implementation, " + "%d: VKCOM, " + "%d: CUDA" % backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Choose one of target computation devices: ' '%d: CPU target (by default), ' '%d: OpenCL, ' '%d: OpenCL fp16 (half-float precision), ' '%d: NCS2 VPU, ' - '%d: HDDL VPU' % targets) + '%d: HDDL VPU, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA fp16 (half-float preprocess)' % targets) parser.add_argument('--async', type=int, default=0, dest='asyncN', help='Number of asynchronous forwards at the same time. ' diff --git a/samples/dnn/person_reid.cpp b/samples/dnn/person_reid.cpp index 23b766114c5b..f0c22e96ad88 100644 --- a/samples/dnn/person_reid.cpp +++ b/samples/dnn/person_reid.cpp @@ -36,13 +36,15 @@ const char* keys = "0: automatically (by default), " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " -"3: OpenCV implementation ," +"3: OpenCV implementation, " +"4: VKCOM, " "5: CUDA }" "{target t | 0 | choose one of target computation devices: " "0: CPU target (by default), " "1: OpenCL, " "2: OpenCL fp16 (half-float precision), " -"6: CUDA ," +"4: Vulkan, " +"6: CUDA, " "7: CUDA fp16 (half-float preprocess) }"; namespace cv{ diff --git a/samples/dnn/person_reid.py b/samples/dnn/person_reid.py index 502f126bd5e1..08f04faa5272 100644 --- a/samples/dnn/person_reid.py +++ b/samples/dnn/person_reid.py @@ -21,6 +21,7 @@ backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV, + cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) targets = (cv.dnn.DNN_TARGET_CPU, @@ -28,6 +29,7 @@ cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL, + cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) @@ -212,7 +214,8 @@ def visualization(topk_idx, query_names, gallery_names, output_dir = 'vis'): help="Choose one of computation backends: " "%d: automatically (by default), " "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "%d: OpenCV implementation" + "%d: OpenCV implementation, " + "%d: VKCOM, " "%d: CUDA backend"% backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Choose one of target computation devices: ' @@ -220,9 +223,10 @@ def visualization(topk_idx, query_names, gallery_names, output_dir = 'vis'): '%d: OpenCL, ' '%d: OpenCL fp16 (half-float precision), ' '%d: NCS2 VPU, ' - '%d: HDDL VPU' - '%d: CUDA,' - '%d: CUDA FP16,' + '%d: HDDL VPU, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA FP16' % targets) args, _ = parser.parse_known_args() diff --git a/samples/dnn/segmentation.cpp b/samples/dnn/segmentation.cpp index d9fbad8974e7..777badf51e2f 100644 --- a/samples/dnn/segmentation.cpp +++ b/samples/dnn/segmentation.cpp @@ -21,12 +21,17 @@ std::string keys = "0: automatically (by default), " "1: Halide language (http://halide-lang.org/), " "2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "3: OpenCV implementation }" + "3: OpenCV implementation, " + "4: VKCOM, " + "5: CUDA }" "{ target | 0 | Choose one of target computation devices: " "0: CPU target (by default), " "1: OpenCL, " "2: OpenCL fp16 (half-float precision), " - "3: VPU }"; + "3: VPU, " + "4: Vulkan, " + "6: CUDA, " + "7: CUDA fp16 (half-float preprocess) }"; using namespace cv; using namespace dnn; diff --git a/samples/dnn/segmentation.py b/samples/dnn/segmentation.py index 8eeb59ba1416..09f3f8dd1159 100644 --- a/samples/dnn/segmentation.py +++ b/samples/dnn/segmentation.py @@ -5,8 +5,10 @@ from common import * -backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV) -targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL) +backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV, + cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) +targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL, + cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--zoo', default=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'models.yml'), @@ -22,14 +24,19 @@ "%d: automatically (by default), " "%d: Halide language (http://halide-lang.org/), " "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "%d: OpenCV implementation" % backends) + "%d: OpenCV implementation, " + "%d: VKCOM, " + "%d: CUDA"% backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Choose one of target computation devices: ' '%d: CPU target (by default), ' '%d: OpenCL, ' '%d: OpenCL fp16 (half-float precision), ' '%d: NCS2 VPU, ' - '%d: HDDL VPU' % targets) + '%d: HDDL VPU, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA fp16 (half-float preprocess)'% targets) args, _ = parser.parse_known_args() add_preproc_args(args.zoo, parser, 'segmentation') parser = argparse.ArgumentParser(parents=[parser], diff --git a/samples/dnn/siamrpnpp.py b/samples/dnn/siamrpnpp.py index c7c49b1b85d9..2e15ec67082e 100644 --- a/samples/dnn/siamrpnpp.py +++ b/samples/dnn/siamrpnpp.py @@ -327,9 +327,11 @@ def main(): """ Sample SiamRPN Tracker """ # Computation backends supported by layers - backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV) + backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV, + cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) # Target Devices for computation - targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD) + targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, + cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) parser = argparse.ArgumentParser(description='Use this script to run SiamRPN++ Visual Tracker', formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -338,17 +340,22 @@ def main(): parser.add_argument('--search_net', type=str, default='search_net.onnx', help='Path to part of SiamRPN++ ran on search frame.') parser.add_argument('--rpn_head', type=str, default='rpn_head.onnx', help='Path to RPN Head ONNX model.') parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DEFAULT, type=int, - help='Select a computation backend: ' - "%d: automatically (by default) " - "%d: Halide" - "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)" - "%d: OpenCV Implementation" % backends) + help="Select a computation backend: " + "%d: automatically (by default), " + "%d: Halide, " + "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " + "%d: OpenCV Implementation, " + "%d: VKCOM, " + "%d: CUDA" % backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Select a target device: ' - "%d: CPU target (by default)" - "%d: OpenCL" - "%d: OpenCL FP16" - "%d: Myriad" % targets) + '%d: CPU target (by default), ' + '%d: OpenCL, ' + '%d: OpenCL FP16, ' + '%d: Myriad, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA fp16 (half-float preprocess)' % targets) args, _ = parser.parse_known_args() if args.input_video and not os.path.isfile(args.input_video): diff --git a/samples/dnn/virtual_try_on.py b/samples/dnn/virtual_try_on.py index 076cb21d5b67..e46f7ece5047 100644 --- a/samples/dnn/virtual_try_on.py +++ b/samples/dnn/virtual_try_on.py @@ -16,8 +16,10 @@ from common import findFile from human_parsing import parse_human -backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV) -targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL) +backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV, + cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA) +targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL, + cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16) parser = argparse.ArgumentParser(description='Use this script to run virtial try-on using CP-VTON', formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -33,14 +35,19 @@ "%d: automatically (by default), " "%d: Halide language (http://halide-lang.org/), " "%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " - "%d: OpenCV implementation" % backends) + "%d: OpenCV implementation, " + "%d: VKCOM, " + "%d: CUDA" % backends) parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int, help='Choose one of target computation devices: ' '%d: CPU target (by default), ' '%d: OpenCL, ' '%d: OpenCL fp16 (half-float precision), ' '%d: NCS2 VPU, ' - '%d: HDDL VPU' % targets) + '%d: HDDL VPU, ' + '%d: Vulkan, ' + '%d: CUDA, ' + '%d: CUDA fp16 (half-float preprocess)'% targets) args, _ = parser.parse_known_args() diff --git a/samples/python/camera_calibration_show_extrinsics.py b/samples/python/camera_calibration_show_extrinsics.py index 0118b5b913d5..d676691f15d7 100755 --- a/samples/python/camera_calibration_show_extrinsics.py +++ b/samples/python/camera_calibration_show_extrinsics.py @@ -188,7 +188,7 @@ def main(): fig = plt.figure() ax = fig.gca(projection='3d') - ax.set_aspect("equal") + ax.set_aspect("auto") cam_width = args.cam_width cam_height = args.cam_height diff --git a/samples/python/gaussian_mix.py b/samples/python/gaussian_mix.py index 5f2dfcc44093..4c1f86794cd6 100755 --- a/samples/python/gaussian_mix.py +++ b/samples/python/gaussian_mix.py @@ -28,11 +28,11 @@ def make_gaussians(cluster_n, img_size): return points, ref_distrs def draw_gaussain(img, mean, cov, color): - x, y = np.int32(mean) + x, y = mean w, u, _vt = cv.SVDecomp(cov) ang = np.arctan2(u[1, 0], u[0, 0])*(180/np.pi) s1, s2 = np.sqrt(w)*3.0 - cv.ellipse(img, (x, y), (s1, s2), ang, 0, 360, color, 1, cv.LINE_AA) + cv.ellipse(img, (int(x), int(y)), (int(s1), int(s2)), ang, 0, 360, color, 1, cv.LINE_AA) def main(): diff --git a/samples/python/hist.py b/samples/python/hist.py index 4c2c1ad395ef..8c1f4546a817 100755 --- a/samples/python/hist.py +++ b/samples/python/hist.py @@ -46,9 +46,9 @@ def hist_lines(im): im = cv.cvtColor(im,cv.COLOR_BGR2GRAY) hist_item = cv.calcHist([im],[0],None,[256],[0,256]) cv.normalize(hist_item,hist_item,0,255,cv.NORM_MINMAX) - hist=np.int32(np.around(hist_item)) + hist = np.int32(np.around(hist_item)) for x,y in enumerate(hist): - cv.line(h,(x,0),(x,y),(255,255,255)) + cv.line(h,(x,0),(x,y[0]),(255,255,255)) y = np.flipud(h) return y diff --git a/samples/python/lk_homography.py b/samples/python/lk_homography.py index 808f30965f0d..38a05f63b6a5 100755 --- a/samples/python/lk_homography.py +++ b/samples/python/lk_homography.py @@ -77,8 +77,8 @@ def run(self): for (x0, y0), (x1, y1), good in zip(self.p0[:,0], self.p1[:,0], status[:,0]): if good: - cv.line(vis, (x0, y0), (x1, y1), (0, 128, 0)) - cv.circle(vis, (x1, y1), 2, (red, green)[good], -1) + cv.line(vis, (int(x0), int(y0)), (int(x1), int(y1)), (0, 128, 0)) + cv.circle(vis, (int(x1), int(y1)), 2, (red, green)[good], -1) draw_str(vis, (20, 20), 'track count: %d' % len(self.p1)) if self.use_ransac: draw_str(vis, (20, 40), 'RANSAC') @@ -86,7 +86,7 @@ def run(self): p = cv.goodFeaturesToTrack(frame_gray, **feature_params) if p is not None: for x, y in p[:,0]: - cv.circle(vis, (x, y), 2, green, -1) + cv.circle(vis, (int(x), int(y)), 2, green, -1) draw_str(vis, (20, 20), 'feature count: %d' % len(p)) cv.imshow('lk_homography', vis) diff --git a/samples/python/lk_track.py b/samples/python/lk_track.py index 7b77f1b33595..97a8c40241e2 100755 --- a/samples/python/lk_track.py +++ b/samples/python/lk_track.py @@ -65,7 +65,7 @@ def run(self): if len(tr) > self.track_len: del tr[0] new_tracks.append(tr) - cv.circle(vis, (x, y), 2, (0, 255, 0), -1) + cv.circle(vis, (int(x), int(y)), 2, (0, 255, 0), -1) self.tracks = new_tracks cv.polylines(vis, [np.int32(tr) for tr in self.tracks], False, (0, 255, 0)) draw_str(vis, (20, 20), 'track count: %d' % len(self.tracks)) diff --git a/samples/python/morphology.py b/samples/python/morphology.py index 9ecf5b0682e7..183f5e828815 100755 --- a/samples/python/morphology.py +++ b/samples/python/morphology.py @@ -50,8 +50,11 @@ def main(): cur_str_mode = str_modes.next() def update(dummy=None): - sz = cv.getTrackbarPos('op/size', 'morphology') - iters = cv.getTrackbarPos('iters', 'morphology') + try: # do not get trackbar position while trackbar is not created + sz = cv.getTrackbarPos('op/size', 'morphology') + iters = cv.getTrackbarPos('iters', 'morphology') + except: + return opers = cur_mode.split('/') if len(opers) > 1: sz = sz - 10 diff --git a/samples/python/stitching_detailed.py b/samples/python/stitching_detailed.py index 7253932167b4..a7e316105edd 100644 --- a/samples/python/stitching_detailed.py +++ b/samples/python/stitching_detailed.py @@ -49,8 +49,6 @@ print("AKAZE not available") SEAM_FIND_CHOICES = OrderedDict() -SEAM_FIND_CHOICES['gc_color'] = cv.detail_GraphCutSeamFinder('COST_COLOR') -SEAM_FIND_CHOICES['gc_colorgrad'] = cv.detail_GraphCutSeamFinder('COST_COLOR_GRAD') SEAM_FIND_CHOICES['dp_color'] = cv.detail_DpSeamFinder('COLOR') SEAM_FIND_CHOICES['dp_colorgrad'] = cv.detail_DpSeamFinder('COLOR_GRAD') SEAM_FIND_CHOICES['voronoi'] = cv.detail.SeamFinder_createDefault(cv.detail.SeamFinder_VORONOI_SEAM) @@ -432,7 +430,7 @@ def main(): compensator.feed(corners=corners, images=images_warped, masks=masks_warped) seam_finder = SEAM_FIND_CHOICES[args.seam] - seam_finder.find(images_warped_f, corners, masks_warped) + masks_warped = seam_finder.find(images_warped_f, corners, masks_warped) compose_scale = 1 corners = [] sizes = [] diff --git a/samples/python/tracker.py b/samples/python/tracker.py index f67499cd15a4..753e166ad896 100644 --- a/samples/python/tracker.py +++ b/samples/python/tracker.py @@ -3,8 +3,22 @@ ''' Tracker demo +For usage download models by following links +For GOTURN: + goturn.prototxt and goturn.caffemodel: https://github.com/opencv/opencv_extra/tree/c4219d5eb3105ed8e634278fad312a1a8d2c182d/testdata/tracking +For DaSiamRPN: + network: https://www.dropbox.com/s/rr1lk9355vzolqv/dasiamrpn_model.onnx?dl=0 + kernel_r1: https://www.dropbox.com/s/999cqx5zrfi7w4p/dasiamrpn_kernel_r1.onnx?dl=0 + kernel_cls1: https://www.dropbox.com/s/qvmtszx5h339a0w/dasiamrpn_kernel_cls1.onnx?dl=0 + USAGE: - tracker.py [] + tracker.py [-h] [--input INPUT] [--tracker_algo TRACKER_ALGO] + [--goturn GOTURN] [--goturn_model GOTURN_MODEL] + [--dasiamrpn_net DASIAMRPN_NET] + [--dasiamrpn_kernel_r1 DASIAMRPN_KERNEL_R1] + [--dasiamrpn_kernel_cls1 DASIAMRPN_KERNEL_CLS1] + [--dasiamrpn_backend DASIAMRPN_BACKEND] + [--dasiamrpn_target DASIAMRPN_TARGET] ''' # Python 2/3 compatibility @@ -14,18 +28,37 @@ import numpy as np import cv2 as cv +import argparse from video import create_capture, presets class App(object): - def initializeTracker(self, image): + def __init__(self, args): + self.args = args + + def initializeTracker(self, image, trackerAlgorithm): while True: + if trackerAlgorithm == 'mil': + tracker = cv.TrackerMIL_create() + elif trackerAlgorithm == 'goturn': + params = cv.TrackerGOTURN_Params() + params.modelTxt = self.args.goturn + params.modelBin = self.args.goturn_model + tracker = cv.TrackerGOTURN_create(params) + elif trackerAlgorithm == 'dasiamrpn': + params = cv.TrackerDaSiamRPN_Params() + params.model = self.args.dasiamrpn_net + params.kernel_cls1 = self.args.dasiamrpn_kernel_cls1 + params.kernel_r1 = self.args.dasiamrpn_kernel_r1 + tracker = cv.TrackerDaSiamRPN_create(params) + else: + sys.exit("Tracker {} is not recognized. Please use one of three available: mil, goturn, dasiamrpn.".format(trackerAlgorithm)) + print('==> Select object ROI for tracker ...') bbox = cv.selectROI('tracking', image) print('ROI: {}'.format(bbox)) - tracker = cv.TrackerMIL_create() try: tracker.init(image, bbox) except Exception as e: @@ -37,7 +70,8 @@ def initializeTracker(self, image): return tracker def run(self): - videoPath = sys.argv[1] if len(sys.argv) >= 2 else 'vtest.avi' + videoPath = self.args.input + trackerAlgorithm = self.args.tracker_algo camera = create_capture(videoPath, presets['cube']) if not camera.isOpened(): sys.exit("Can't open video stream: {}".format(videoPath)) @@ -48,7 +82,7 @@ def run(self): assert image is not None cv.namedWindow('tracking') - tracker = self.initializeTracker(image) + tracker = self.initializeTracker(image, trackerAlgorithm) print("==> Tracking is started. Press 'SPACE' to re-initialize tracker or 'ESC' for exit...") @@ -76,5 +110,24 @@ def run(self): if __name__ == '__main__': print(__doc__) - App().run() + parser = argparse.ArgumentParser(description="Run tracker") + parser.add_argument("--input", type=str, default="vtest.avi", help="Path to video source") + parser.add_argument("--tracker_algo", type=str, default="mil", help="One of three available tracking algorithms: mil, goturn, dasiamrpn") + parser.add_argument("--goturn", type=str, default="goturn.prototxt", help="Path to GOTURN architecture") + parser.add_argument("--goturn_model", type=str, default="goturn.caffemodel", help="Path to GOTERN model") + parser.add_argument("--dasiamrpn_net", type=str, default="dasiamrpn_model.onnx", help="Path to onnx model of DaSiamRPN net") + parser.add_argument("--dasiamrpn_kernel_r1", type=str, default="dasiamrpn_kernel_r1.onnx", help="Path to onnx model of DaSiamRPN kernel_r1") + parser.add_argument("--dasiamrpn_kernel_cls1", type=str, default="dasiamrpn_kernel_cls1.onnx", help="Path to onnx model of DaSiamRPN kernel_cls1") + parser.add_argument("--dasiamrpn_backend", type=int, default=0, help="Choose one of computation backends:\ + 0: automatically (by default),\ + 1: Halide language (http://halide-lang.org/),\ + 2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit),\ + 3: OpenCV implementation") + parser.add_argument("--dasiamrpn_target", type=int, default=0, help="Choose one of target computation devices:\ + 0: CPU target (by default),\ + 1: OpenCL,\ + 2: OpenCL fp16 (half-float precision),\ + 3: VPU") + args = parser.parse_args() + App(args).run() cv.destroyAllWindows() diff --git a/samples/python/video_v4l2.py b/samples/python/video_v4l2.py index 61b1e3580483..abebb2a2cacc 100644 --- a/samples/python/video_v4l2.py +++ b/samples/python/video_v4l2.py @@ -30,7 +30,7 @@ def decode_fourcc(v): color = (0, 255, 0) cap = cv.VideoCapture(0) - cap.set(cv.CAP_PROP_AUTOFOCUS, False) # Known bug: https://github.com/opencv/opencv/pull/5474 + cap.set(cv.CAP_PROP_AUTOFOCUS, 0) # Known bug: https://github.com/opencv/opencv/pull/5474 cv.namedWindow("Video") @@ -67,7 +67,7 @@ def decode_fourcc(v): break elif k == ord('g'): convert_rgb = not convert_rgb - cap.set(cv.CAP_PROP_CONVERT_RGB, convert_rgb) + cap.set(cv.CAP_PROP_CONVERT_RGB, 1 if convert_rgb else 0) print('Done') diff --git a/samples/wp8/OcvImageManipulation/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs b/samples/wp8/OcvImageManipulation/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs index fd2a7c846647..73190e28f329 100644 --- a/samples/wp8/OcvImageManipulation/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs +++ b/samples/wp8/OcvImageManipulation/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs @@ -207,7 +207,7 @@ private void InitializeLanguage() catch { // If an exception is caught here it is most likely due to either - // ResourceLangauge not being correctly set to a supported language + // ResourceLanguage not being correctly set to a supported language // code or ResourceFlowDirection is set to a value other than LeftToRight // or RightToLeft. @@ -220,4 +220,4 @@ private void InitializeLanguage() } } } -} \ No newline at end of file +} diff --git a/samples/wp8/OcvRotatingCube/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs b/samples/wp8/OcvRotatingCube/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs index fd2a7c846647..73190e28f329 100644 --- a/samples/wp8/OcvRotatingCube/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs +++ b/samples/wp8/OcvRotatingCube/PhoneXamlDirect3DApp1/PhoneXamlDirect3DApp1/App.xaml.cs @@ -207,7 +207,7 @@ private void InitializeLanguage() catch { // If an exception is caught here it is most likely due to either - // ResourceLangauge not being correctly set to a supported language + // ResourceLanguage not being correctly set to a supported language // code or ResourceFlowDirection is set to a value other than LeftToRight // or RightToLeft. @@ -220,4 +220,4 @@ private void InitializeLanguage() } } } -} \ No newline at end of file +} diff --git a/samples/wp8/OpenCVXaml/OpenCVXaml/App.xaml.cs b/samples/wp8/OpenCVXaml/OpenCVXaml/App.xaml.cs index 6fe3a54410bb..17f8fed93ec3 100644 --- a/samples/wp8/OpenCVXaml/OpenCVXaml/App.xaml.cs +++ b/samples/wp8/OpenCVXaml/OpenCVXaml/App.xaml.cs @@ -207,7 +207,7 @@ private void InitializeLanguage() catch { // If an exception is caught here it is most likely due to either - // ResourceLangauge not being correctly set to a supported language + // ResourceLanguage not being correctly set to a supported language // code or ResourceFlowDirection is set to a value other than LeftToRight // or RightToLeft. @@ -220,4 +220,4 @@ private void InitializeLanguage() } } } -} \ No newline at end of file +}