|
- // Copyright 2017 Tencent
- // SPDX-License-Identifier: BSD-3-Clause
-
- #ifndef NCNN_PLATFORM_H
- #define NCNN_PLATFORM_H
-
- #cmakedefine01 NCNN_STDIO
- #cmakedefine01 NCNN_STRING
- #cmakedefine01 NCNN_SIMPLEOCV
- #cmakedefine01 NCNN_SIMPLEOMP
- #cmakedefine01 NCNN_SIMPLESTL
- #cmakedefine01 NCNN_SIMPLEMATH
- #cmakedefine01 NCNN_THREADS
- #cmakedefine01 NCNN_BENCHMARK
- #cmakedefine01 NCNN_C_API
- #cmakedefine01 NCNN_PLATFORM_API
- #cmakedefine01 NCNN_PIXEL
- #cmakedefine01 NCNN_PIXEL_ROTATE
- #cmakedefine01 NCNN_PIXEL_AFFINE
- #cmakedefine01 NCNN_PIXEL_DRAWING
- #cmakedefine01 NCNN_VULKAN
- #cmakedefine01 NCNN_SIMPLEVK
- #cmakedefine01 NCNN_SYSTEM_GLSLANG
- #cmakedefine01 NCNN_RUNTIME_CPU
- #cmakedefine01 NCNN_GNU_INLINE_ASM
- #cmakedefine01 NCNN_AVX
- #cmakedefine01 NCNN_XOP
- #cmakedefine01 NCNN_FMA
- #cmakedefine01 NCNN_F16C
- #cmakedefine01 NCNN_AVX2
- #cmakedefine01 NCNN_AVXVNNI
- #cmakedefine01 NCNN_AVXVNNIINT8
- #cmakedefine01 NCNN_AVXVNNIINT16
- #cmakedefine01 NCNN_AVXNECONVERT
- #cmakedefine01 NCNN_AVX512
- #cmakedefine01 NCNN_AVX512VNNI
- #cmakedefine01 NCNN_AVX512BF16
- #cmakedefine01 NCNN_AVX512FP16
- #cmakedefine01 NCNN_VFPV4
- #cmakedefine01 NCNN_ARM82
- #cmakedefine01 NCNN_ARM82DOT
- #cmakedefine01 NCNN_ARM82FP16FML
- #cmakedefine01 NCNN_ARM84BF16
- #cmakedefine01 NCNN_ARM84I8MM
- #cmakedefine01 NCNN_ARM86SVE
- #cmakedefine01 NCNN_ARM86SVE2
- #cmakedefine01 NCNN_ARM86SVEBF16
- #cmakedefine01 NCNN_ARM86SVEI8MM
- #cmakedefine01 NCNN_ARM86SVEF32MM
- #cmakedefine01 NCNN_MSA
- #cmakedefine01 NCNN_LSX
- #cmakedefine01 NCNN_MMI
- #cmakedefine01 NCNN_RVV
- #cmakedefine01 NCNN_ZFH
- #cmakedefine01 NCNN_ZVFH
- #cmakedefine01 NCNN_XTHEADVECTOR
- #cmakedefine01 NCNN_INT8
- #cmakedefine01 NCNN_BF16
- #cmakedefine01 NCNN_FORCE_INLINE
-
- #cmakedefine NCNN_VERSION_STRING "@NCNN_VERSION_STRING@"
-
- #include "ncnn_export.h"
-
- #ifdef __cplusplus
-
- #if NCNN_THREADS
- #if defined _WIN32
- #define WIN32_LEAN_AND_MEAN
- #ifndef _WIN32_WINNT
- #define _WIN32_WINNT 0x0501
- #endif
- #include <windows.h>
- #include <process.h>
- #else
- #include <pthread.h>
- #endif
- #endif // NCNN_THREADS
-
- #if __ANDROID_API__ >= 26
- #ifndef VK_USE_PLATFORM_ANDROID_KHR
- #define VK_USE_PLATFORM_ANDROID_KHR
- #endif
- #endif // __ANDROID_API__ >= 26
-
- namespace ncnn {
-
- #if NCNN_THREADS
- #if defined _WIN32
- #if _WIN32_WINNT > _WIN32_WINNT_WINXP // Windows Vista and later
- class NCNN_EXPORT Mutex
- {
- public:
- Mutex() { InitializeSRWLock(&srwlock); }
- ~Mutex() {}
- void lock() { AcquireSRWLockExclusive(&srwlock); }
- void unlock() { ReleaseSRWLockExclusive(&srwlock); }
- private:
- friend class ConditionVariable;
- SRWLOCK srwlock;
- };
-
- class NCNN_EXPORT ConditionVariable
- {
- public:
- ConditionVariable() { InitializeConditionVariable(&condvar); }
- ~ConditionVariable() {}
- void wait(Mutex& mutex) { SleepConditionVariableSRW(&condvar, &mutex.srwlock, INFINITE, 0); }
- void broadcast() { WakeAllConditionVariable(&condvar); }
- void signal() { WakeConditionVariable(&condvar); }
- private:
- CONDITION_VARIABLE condvar;
- };
-
- #else // Windows XP compatibility
-
- class NCNN_EXPORT Mutex
- {
- public:
- Mutex() { InitializeCriticalSection(&cs); }
- ~Mutex() { DeleteCriticalSection(&cs); }
- void lock() { EnterCriticalSection(&cs); }
- void unlock() { LeaveCriticalSection(&cs); }
- private:
- friend class ConditionVariable;
- CRITICAL_SECTION cs;
- };
-
- class NCNN_EXPORT ConditionVariable
- {
- public:
- ConditionVariable()
- {
- signal_event = CreateEvent(0, FALSE, FALSE, 0); // Auto-reset event for signal()
- broadcast_event = CreateEvent(0, TRUE, FALSE, 0); // Manual-reset event for broadcast()
- }
- ~ConditionVariable()
- {
- CloseHandle(signal_event);
- CloseHandle(broadcast_event);
- }
- void wait(Mutex& mutex)
- {
- mutex.unlock();
- HANDLE events[2] = { signal_event, broadcast_event };
- WaitForMultipleObjects(2, events, FALSE, INFINITE); // Wait for either signal or broadcast
- mutex.lock();
- }
- void broadcast()
- {
- SetEvent(broadcast_event); // Wake all threads
- ResetEvent(broadcast_event); // Reset after waking all threads
- }
- void signal()
- {
- SetEvent(signal_event); // Wake one thread
- }
- private:
- HANDLE signal_event;
- HANDLE broadcast_event;
- };
-
- #endif // _WIN32_WINNT > _WIN32_WINNT_WINXP
-
- static unsigned __stdcall start_wrapper(void* args);
- class NCNN_EXPORT Thread
- {
- public:
- Thread(void* (*start)(void*), void* args = 0) { _start = start; _args = args; handle = (HANDLE)_beginthreadex(0, 0, start_wrapper, this, 0, 0); }
- ~Thread() {}
- void join() { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); }
- private:
- friend unsigned __stdcall start_wrapper(void* args)
- {
- Thread* t = (Thread*)args;
- t->_start(t->_args);
- return 0;
- }
- HANDLE handle;
- void* (*_start)(void*);
- void* _args;
- };
-
- class NCNN_EXPORT ThreadLocalStorage
- {
- public:
- ThreadLocalStorage() { key = TlsAlloc(); }
- ~ThreadLocalStorage() { TlsFree(key); }
- void set(void* value) { TlsSetValue(key, (LPVOID)value); }
- void* get() { return (void*)TlsGetValue(key); }
- private:
- DWORD key;
- };
- #else // defined _WIN32
- class NCNN_EXPORT Mutex
- {
- public:
- Mutex() { pthread_mutex_init(&mutex, 0); }
- ~Mutex() { pthread_mutex_destroy(&mutex); }
- void lock() { pthread_mutex_lock(&mutex); }
- void unlock() { pthread_mutex_unlock(&mutex); }
- private:
- friend class ConditionVariable;
- pthread_mutex_t mutex;
- };
-
- class NCNN_EXPORT ConditionVariable
- {
- public:
- ConditionVariable() { pthread_cond_init(&cond, 0); }
- ~ConditionVariable() { pthread_cond_destroy(&cond); }
- void wait(Mutex& mutex) { pthread_cond_wait(&cond, &mutex.mutex); }
- void broadcast() { pthread_cond_broadcast(&cond); }
- void signal() { pthread_cond_signal(&cond); }
- private:
- pthread_cond_t cond;
- };
-
- class NCNN_EXPORT Thread
- {
- public:
- Thread(void* (*start)(void*), void* args = 0) { pthread_create(&t, 0, start, args); }
- ~Thread() {}
- void join() { pthread_join(t, 0); }
- private:
- pthread_t t;
- };
-
- class NCNN_EXPORT ThreadLocalStorage
- {
- public:
- ThreadLocalStorage() { pthread_key_create(&key, 0); }
- ~ThreadLocalStorage() { pthread_key_delete(key); }
- void set(void* value) { pthread_setspecific(key, value); }
- void* get() { return pthread_getspecific(key); }
- private:
- pthread_key_t key;
- };
- #endif // defined _WIN32
- #else // NCNN_THREADS
- class NCNN_EXPORT Mutex
- {
- public:
- Mutex() {}
- ~Mutex() {}
- void lock() {}
- void unlock() {}
- };
-
- class NCNN_EXPORT ConditionVariable
- {
- public:
- ConditionVariable() {}
- ~ConditionVariable() {}
- void wait(Mutex& /*mutex*/) {}
- void broadcast() {}
- void signal() {}
- };
-
- class NCNN_EXPORT Thread
- {
- public:
- Thread(void* (*/*start*/)(void*), void* /*args*/ = 0) {}
- ~Thread() {}
- void join() {}
- };
-
- class NCNN_EXPORT ThreadLocalStorage
- {
- public:
- ThreadLocalStorage() { data = 0; }
- ~ThreadLocalStorage() {}
- void set(void* value) { data = value; }
- void* get() { return data; }
- private:
- void* data;
- };
- #endif // NCNN_THREADS
-
- class NCNN_EXPORT MutexLockGuard
- {
- public:
- MutexLockGuard(Mutex& _mutex) : mutex(_mutex) { mutex.lock(); }
- ~MutexLockGuard() { mutex.unlock(); }
- private:
- Mutex& mutex;
- };
-
- static inline void swap_endianness_16(void* x)
- {
- unsigned char* xx = (unsigned char*)x;
- unsigned char x0 = xx[0];
- unsigned char x1 = xx[1];
- xx[0] = x1;
- xx[1] = x0;
- }
-
- static inline void swap_endianness_32(void* x)
- {
- unsigned char* xx = (unsigned char*)x;
- unsigned char x0 = xx[0];
- unsigned char x1 = xx[1];
- unsigned char x2 = xx[2];
- unsigned char x3 = xx[3];
- xx[0] = x3;
- xx[1] = x2;
- xx[2] = x1;
- xx[3] = x0;
- }
-
- } // namespace ncnn
-
- #if NCNN_SIMPLESTL
- #include "simplestl.h"
- #else
- #include <algorithm>
- #include <list>
- #include <vector>
- #include <stack>
- #include <string>
- #endif
-
- // simplemath
- #if NCNN_SIMPLEMATH
- #include "simplemath.h"
- #else
- #include <math.h>
- #include <fenv.h>
- #endif
-
- #if NCNN_VULKAN
- #if NCNN_SIMPLEVK
- #include "simplevk.h"
- #else
- #include <vulkan/vulkan.h>
- #endif
- #include "vulkan_header_fix.h"
- #endif // NCNN_VULKAN
-
- #endif // __cplusplus
-
- #if NCNN_STDIO
- #if NCNN_PLATFORM_API && __ANDROID_API__ >= 8
- #include <android/log.h>
- #define NCNN_LOGE(...) do { \
- fprintf(stderr, ##__VA_ARGS__); fprintf(stderr, "\n"); \
- __android_log_print(ANDROID_LOG_WARN, "ncnn", ##__VA_ARGS__); } while(0)
- #else // NCNN_PLATFORM_API && __ANDROID_API__ >= 8
- #include <stdio.h>
- #define NCNN_LOGE(...) do { \
- fprintf(stderr, ##__VA_ARGS__); fprintf(stderr, "\n"); } while(0)
- #endif // NCNN_PLATFORM_API && __ANDROID_API__ >= 8
- #else
- #define NCNN_LOGE(...)
- #endif
-
-
- #if NCNN_FORCE_INLINE
- #ifdef _MSC_VER
- #define NCNN_FORCEINLINE __forceinline
- #elif defined(__GNUC__)
- #define NCNN_FORCEINLINE inline __attribute__((__always_inline__))
- #elif defined(__CLANG__)
- #if __has_attribute(__always_inline__)
- #define NCNN_FORCEINLINE inline __attribute__((__always_inline__))
- #else
- #define NCNN_FORCEINLINE inline
- #endif
- #else
- #define NCNN_FORCEINLINE inline
- #endif
- #else
- #define NCNN_FORCEINLINE inline
- #endif
-
- #endif // NCNN_PLATFORM_H
|