23#ifndef MOCHI_PLATFORM_H
24#define MOCHI_PLATFORM_H
26#if defined(__cplusplus)
37#if defined(__cplusplus)
38#define MOCHI_LANGUAGE_CPP 1
39#define MOCHI_LANGUAGE_CPP17 (__cplusplus >= 201703L)
40#ifndef MOCHI_LANGUAGE_CPP20
41#define MOCHI_LANGUAGE_CPP20 (__cplusplus >= 202002L)
43#define MOCHI_LANGUAGE_C 0
45#define MOCHI_LANGUAGE_CPP 0
46#define MOCHI_LANGUAGE_CPP17 0
47#ifndef MOCHI_LANGUAGE_CPP20
48#define MOCHI_LANGUAGE_CPP20 0
50#define MOCHI_LANGUAGE_C 1
69#if defined(__CUDA_ARCH__)
70#define MOCHI_ARCH_CPU 0
71#define MOCHI_ARCH_GPU 1
73#define MOCHI_ARCH_CPU 1
74#define MOCHI_ARCH_GPU 0
78#if defined(PLATFORM_ENABLE_VECTORINTRINSICS_NEON) && PLATFORM_ENABLE_VECTORINTRINSICS_NEON
79#define MOCHI_UNREAL_ARCH_NEON 1
81#define MOCHI_UNREAL_ARCH_NEON 0
84#if defined(__aarch64__) || MOCHI_UNREAL_ARCH_NEON
85#define MOCHI_ARCH_ARM 1
87#define MOCHI_ARCH_ARM 0
90#if MOCHI_ARCH_CPU && MOCHI_ARCH_ARM && (defined(__ARM_NEON) || MOCHI_UNREAL_ARCH_NEON)
91#define MOCHI_ARCH_ARM_NEON 1
93#define MOCHI_ARCH_ARM_NEON 0
96#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
97#define MOCHI_ARCH_ARM_NEON_FP16_ARITHMETIC 1
99#define MOCHI_ARCH_ARM_NEON_FP16_ARITHMETIC 0
103#define MOCHI_UNREAL_ARCH_AVX2 0
105#if defined(PLATFORM_CPU_X86_FAMILY)
106#if PLATFORM_CPU_X86_FAMILY
107#undef MOCHI_UNREAL_ARCH_AVX2
108#define MOCHI_UNREAL_ARCH_AVX2 1
116#if defined(UNREALIOS_LINUX_EDITOR)
117#if UNREALIOS_LINUX_EDITOR
118#undef MOCHI_UNREAL_ARCH_AVX2
119#define MOCHI_UNREAL_ARCH_AVX2 0
123#if defined(_M_X64) || defined(__x86_64) || MOCHI_UNREAL_ARCH_AVX2
124#define MOCHI_ARCH_X64 1
126#define MOCHI_ARCH_X64 0
129#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64 && defined(__AVX512F__) && defined(__AVX512CD__) && \
130 defined(__AVX512BW__) && defined(__AVX512DQ__) && defined(__AVX512VL__)
131#define MOCHI_ARCH_X64_AVX512 1
133#define MOCHI_ARCH_X64_AVX512 0
136#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64 && \
137 (MOCHI_ARCH_X64_AVX512 || defined(__AVX2__) || MOCHI_UNREAL_ARCH_AVX2)
138#define MOCHI_ARCH_X64_AVX2 1
140#define MOCHI_ARCH_X64_AVX2 0
143#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64_AVX2 && \
144 (defined(__FMA__) || (defined(_MSC_VER) && !defined(__clang__)))
145#define MOCHI_ARCH_X64_FMA 1
147#define MOCHI_ARCH_X64_FMA 0
150#if MOCHI_ARCH_CPU && MOCHI_ARCH_X64_AVX2 && \
151 (defined(__SVML__) || (defined(_MSC_VER) && !defined(__clang__)))
152#define MOCHI_ARCH_X64_SVML 1
154#define MOCHI_ARCH_X64_SVML 0
158#if !MOCHI_ARCH_ARM && (defined(__arm__) || defined(_M_ARM))
159#error Mochi does not support older 32-bit versions of ARM
161#if MOCHI_ARCH_ARM && MOCHI_ARCH_X64
162#error Failed to detect correct architecture
164#if MOCHI_UNREAL_ARCH_AVX2 && MOCHI_UNREAL_ARCH_NEON
165#error Cannot have both AVX and NEON
184#if defined(_MSC_VER) && !defined(__clang__)
188#define MOCHI_COMPILER_MSVC 1
190#define MOCHI_COMPILER_MSVC 0
195#if defined(_MSVC_TRADITIONAL)
196#define MOCHI_MSVC_TRADITIONAL _MSVC_TRADITIONAL
198#define MOCHI_MSVC_TRADITIONAL 0
201#if defined(__GNUC__) && !defined(__clang__)
202#define MOCHI_COMPILER_GCC 1
204#define MOCHI_COMPILER_GCC 0
206#if defined(__clang__)
207#define MOCHI_COMPILER_CLANG 1
208#if (__clang_major__ < 19)
209#define MOCHI_CLANG_AWAIT_SUSPEND_BUG 1
211#define MOCHI_CLANG_AWAIT_SUSPEND_BUG 0
214#define MOCHI_COMPILER_CLANG 0
215#define MOCHI_CLANG_AWAIT_SUSPEND_BUG 0
218#if defined(__CUDA_ARCH__)
219#define MOCHI_COMPILER_CUDA_CPU 0
220#define MOCHI_COMPILER_CUDA_GPU 1
221#define MOCHI_COMPILER_CUDA 1
222#elif defined(__CUDACC__)
223#define MOCHI_COMPILER_CUDA_CPU 1
224#define MOCHI_COMPILER_CUDA_GPU 0
225#define MOCHI_COMPILER_CUDA 1
227#define MOCHI_COMPILER_CUDA_CPU 0
228#define MOCHI_COMPILER_CUDA_GPU 0
229#define MOCHI_COMPILER_CUDA 0
233#if defined(__SANITIZE_ADDRESS__) && (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
234#define MOCHI_COMPILER_ASAN 1
236#define MOCHI_COMPILER_ASAN 0
238#if defined(__SANITIZE_THREAD__) && (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
239#define MOCHI_COMPILER_TSAN 1
241#define MOCHI_COMPILER_TSAN 0
243#if (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
244#if defined(__has_feature)
245#if __has_feature(address_sanitizer)
246#undef MOCHI_COMPILER_ASAN
247#define MOCHI_COMPILER_ASAN 1
250#if defined(__has_feature)
251#if __has_feature(thread_sanitizer)
252#undef MOCHI_COMPILER_TSAN
253#define MOCHI_COMPILER_TSAN 1
258#if MOCHI_COMPILER_CLANG
259#if __has_feature(cxx_rtti)
260#define MOCHI_COMPILER_HAS_RTTI 1
262#define MOCHI_COMPILER_HAS_RTTI 0
264#elif MOCHI_COMPILER_GCC
266#define MOCHI_COMPILER_HAS_RTTI 1
268#define MOCHI_COMPILER_HAS_RTTI 0
270#elif MOCHI_COMPILER_MSVC
272#define MOCHI_COMPILER_HAS_RTTI 1
274#define MOCHI_COMPILER_HAS_RTTI 0
279#define MOCHI_COMPILER_HAS_RTTI 1
285#define MOCHI_HAS_VA_OPT (MOCHI_LANGUAGE_CPP20 && !MOCHI_MSVC_TRADITIONAL)
295#if defined(__ANDROID__)
296#define MOCHI_PLATFORM_ANDROID 1
298#define MOCHI_PLATFORM_ANDROID 0
301#if defined(__linux__) && !defined(__ANDROID__)
302#define MOCHI_PLATFORM_LINUX 1
304#define MOCHI_PLATFORM_LINUX 0
307#if defined(__APPLE__)
308#define MOCHI_PLATFORM_MACOS 1
310#define MOCHI_PLATFORM_MACOS 0
314#define MOCHI_PLATFORM_WINDOWS 1
316#define MOCHI_PLATFORM_WINDOWS 0
326#if MOCHI_COMPILER_CUDA
327#define MOCHI_ANY __host__ __device__
328#define MOCHI_CPU __host__
329#define MOCHI_GPU __device__
330#define MOCHI_GPU_KERNEL __global__
335#define MOCHI_GPU_KERNEL
349#if MOCHI_COMPILER_CUDA_GPU
350#define MOCHI_FORCE_INLINE __forceinline__
351#elif MOCHI_COMPILER_MSVC
352#define MOCHI_FORCE_INLINE __forceinline
354#define MOCHI_FORCE_INLINE __attribute__((always_inline)) inline
357#define MOCHI_FORCE_INLINE inline
378#if MOCHI_COMPILER_CUDA_GPU
379#define MOCHI_FORCE_INLINE_LAMBDA
380#elif (MOCHI_COMPILER_CLANG || MOCHI_COMPILER_GCC)
381#define MOCHI_FORCE_INLINE_LAMBDA __attribute__((always_inline))
383#if defined(__has_cpp_attribute)
384#if __has_cpp_attribute(msvc::forceinline)
385#define MOCHI_FORCE_INLINE_LAMBDA [[msvc::forceinline]]
387#define MOCHI_FORCE_INLINE_LAMBDA
390#define MOCHI_FORCE_INLINE_LAMBDA
394#define MOCHI_FORCE_INLINE_LAMBDA
410#if MOCHI_COMPILER_CUDA_GPU
411#define MOCHI_UNROLL_LOOP_N(N) _Pragma(MOCHI_PP_STRINGIFY(unroll N))
412#elif MOCHI_COMPILER_MSVC
413#define MOCHI_UNROLL_LOOP_N(N)
414#elif MOCHI_COMPILER_GCC
415#define MOCHI_UNROLL_LOOP_N(N) _Pragma(MOCHI_PP_STRINGIFY(GCC unroll N))
416#elif MOCHI_COMPILER_CLANG
417#define MOCHI_UNROLL_LOOP_N(N) _Pragma(MOCHI_PP_STRINGIFY(unroll N))
419#define MOCHI_UNROLL_LOOP_N(N)
429#if MOCHI_COMPILER_CUDA_GPU
430#define MOCHI_NO_INLINE __noinline__
431#elif MOCHI_COMPILER_MSVC
432#define MOCHI_NO_INLINE __declspec(noinline)
434#define MOCHI_NO_INLINE __attribute__((noinline))
449#if MOCHI_COMPILER_CUDA_GPU || MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG
450#define MOCHI_RESTRICT __restrict__
451#elif MOCHI_COMPILER_MSVC
452#define MOCHI_RESTRICT __restrict
454#define MOCHI_RESTRICT restrict
462#if MOCHI_ARCH_X64_AVX512
463#define MOCHI_SIMD_REGISTER_COUNT 32
464#define MOCHI_SIMD_REGISTER_SIZE_BYTES 64
465#elif MOCHI_ARCH_X64_AVX2
466#define MOCHI_SIMD_REGISTER_COUNT 16
467#define MOCHI_SIMD_REGISTER_SIZE_BYTES 32
468#elif MOCHI_ARCH_ARM_NEON
469#define MOCHI_SIMD_REGISTER_COUNT 32
470#define MOCHI_SIMD_REGISTER_SIZE_BYTES 16
472#define MOCHI_SIMD_REGISTER_COUNT Unsupported architecture
473#define MOCHI_SIMD_REGISTER_SIZE_BYTES Unsupported architecture
489#ifndef MOCHI_CONSERVATIVE_CACHE_LINE_SIZE
490#define MOCHI_CONSERVATIVE_CACHE_LINE_SIZE 256
502#define MOCHI_CONSERVATIVE_CACHE_ALIGN alignas(MOCHI_CONSERVATIVE_CACHE_LINE_SIZE)
513#if MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG
515#define MOCHI_NO_INIT __attribute__((uninitialized))
527#if MOCHI_COMPILER_CUDA_GPU
528#define MOCHI_DEBUG_BREAK() asm("brkpt;")
529#elif MOCHI_PLATFORM_WINDOWS
530#define MOCHI_DEBUG_BREAK() __debugbreak()
532#define MOCHI_DEBUG_BREAK() __builtin_trap()
556#if MOCHI_COMPILER_CUDA_GPU
557#define MOCHI_WARNING_PUSH()
558#define MOCHI_WARNING_PUSH_IGNORE_ALL()
559#define MOCHI_WARNING_POP()
560#elif MOCHI_COMPILER_MSVC
561#define MOCHI_WARNING_PUSH() __pragma(warning(push))
562#define MOCHI_WARNING_PUSH_IGNORE_ALL() __pragma(warning(push, 0))
563#define MOCHI_WARNING_POP() __pragma(warning(pop))
564#elif MOCHI_COMPILER_CLANG
565#define MOCHI_WARNING_PUSH() _Pragma("GCC diagnostic push")
566#define MOCHI_WARNING_PUSH_IGNORE_ALL() \
567 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Weverything\"")
568#define MOCHI_WARNING_POP() _Pragma("GCC diagnostic pop")
569#elif MOCHI_COMPILER_GCC
570#define MOCHI_WARNING_PUSH() _Pragma("GCC diagnostic push")
571#define MOCHI_WARNING_PUSH_IGNORE_ALL() \
572 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wall\"") \
573 _Pragma("GCC diagnostic ignored \"-Wextra\"")
574#define MOCHI_WARNING_POP() _Pragma("GCC diagnostic pop")
576#define MOCHI_WARNING_PUSH()
577#define MOCHI_WARNING_PUSH_IGNORE_ALL()
578#define MOCHI_WARNING_POP()
581#if MOCHI_COMPILER_MSVC
582#define MOCHI_WARNING_IGNORE_MSVC(X) __pragma(warning(disable : X))
583#define MOCHI_WARNING_ENFORCE_MSVC(X) __pragma(warning(error : X))
585#define MOCHI_WARNING_IGNORE_MSVC(X)
586#define MOCHI_WARNING_ENFORCE_MSVC(X)
589#if MOCHI_COMPILER_GCC
590#define MOCHI_WARNING_IGNORE_GCC(X) _Pragma(#X)
591#define MOCHI_WARNING_ENFORCE_GCC(X) _Pragma(#X)
593#define MOCHI_WARNING_IGNORE_GCC(X)
594#define MOCHI_WARNING_ENFORCE_GCC(X)
597#if MOCHI_COMPILER_CLANG
598#define MOCHI_WARNING_IGNORE_CLANG(X) _Pragma(#X)
599#define MOCHI_WARNING_ENFORCE_CLANG(X) _Pragma(#X)
601#define MOCHI_WARNING_IGNORE_CLANG(X)
602#define MOCHI_WARNING_ENFORCE_CLANG(X)
606#if MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG
607#define MOCHI_WARNING_IGNORE_GCC_CLANG(X) _Pragma(#X)
608#define MOCHI_WARNING_ENFORCE_GCC_CLANG(X) _Pragma(#X)
610#define MOCHI_WARNING_IGNORE_GCC_CLANG(X)
611#define MOCHI_WARNING_ENFORCE_GCC_CLANG(X)
627#if MOCHI_COMPILER_CUDA
628#define MOCHI_WARNING_IGNORE_CUDA(X) __pragma(diag_suppress = X)
629#define MOCHI_WARNING_ENFORCE_CUDA(X) __pragma(diag_error = X)
631#define MOCHI_WARNING_IGNORE_CUDA(X)
632#define MOCHI_WARNING_ENFORCE_CUDA(X)
638#if MOCHI_COMPILER_CUDA_GPU
639#if __CUDAVER__ >= 75000
640#define MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK() __pragma(nv_exec_check_disable)
642#define MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK()
645#define MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK()
648#define MOCHI_TEMPLATE_FUNCTION MOCHI_DISABLE_CUDA_GPU_EXEC_CHECK()
653#define MOCHI_WARNING_SUPPRESS_CUDA() \
655 MOCHI_WARNING_IGNORE_MSVC(4201) \
657 MOCHI_WARNING_IGNORE_MSVC(4244) \
659 MOCHI_WARNING_IGNORE_MSVC(4324) \
661 MOCHI_WARNING_IGNORE_MSVC(4458) \
663 MOCHI_WARNING_IGNORE_MSVC(4505) \
665 MOCHI_WARNING_IGNORE_MSVC(4700) \
667 MOCHI_WARNING_IGNORE_MSVC(4706) \
670 MOCHI_WARNING_IGNORE_CUDA(implicit_return_from_non_void_function)
676#define MOCHI_WARNING_SUPPRESS_EIGEN() \
678 MOCHI_WARNING_IGNORE_MSVC(4127) \
680 MOCHI_WARNING_IGNORE_MSVC(4554) \
682 MOCHI_WARNING_IGNORE_MSVC(4245) \
684 MOCHI_WARNING_IGNORE_CUDA(esa_on_defaulted_function_ignored)
692#if MOCHI_COMPILER_MSVC
693#define MOCHI_DEBUG_RTCHECKS_ENABLE() __pragma(runtime_checks("sc", restore))
694#define MOCHI_DEBUG_RTCHECKS_DISABLE() __pragma(runtime_checks("sc", off))
696#define MOCHI_DEBUG_RTCHECKS_ENABLE()
697#define MOCHI_DEBUG_RTCHECKS_DISABLE()
704#if MOCHI_COMPILER_MSVC
706#define MOCHI_NOP() __nop();
708#define MOCHI_NOP() __asm__ __volatile__("nop");
711#define MOCHI_NOP_10() \
712 MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); \
713 MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP(); MOCHI_NOP();
714#define MOCHI_NOP_50() \
715 MOCHI_NOP_10(); MOCHI_NOP_10(); MOCHI_NOP_10(); MOCHI_NOP_10(); MOCHI_NOP_10();
716#define MOCHI_NOP_250() \
717 MOCHI_NOP_50(); MOCHI_NOP_50(); MOCHI_NOP_50(); MOCHI_NOP_50(); MOCHI_NOP_50();
725#define MOCHI_PP_CAT(a, b) MOCHI_PP_CAT_IMPL(a, b)
726#define MOCHI_PP_CAT_IMPL(a, b) a##b
729#define MOCHI_PP_STRINGIFY(X) MOCHI_PP_STRINGIFY_IMPL(X)
730#define MOCHI_PP_STRINGIFY_IMPL(X) #X
737#define MOCHI_DECLARE_MOVE(Name) \
738 Name(Name&&) noexcept = default; \
739 Name& operator=(Name&&) = default;
742#define MOCHI_DECLARE_NO_MOVE(Name) \
743 Name(Name&&) = delete; \
744 Name& operator=(Name&&) = delete;
748#define MOCHI_DECLARE_COPY(Name) \
749 Name(Name const&) = default; \
750 Name& operator=(Name const&) = default;
753#define MOCHI_DECLARE_NO_COPY(Name) \
754 Name(Name const&) = delete; \
755 Name& operator=(Name const&) = delete;
760#define MOCHI_DECLARE_NO_COPY_NO_MOVE(Name) \
761 MOCHI_DECLARE_NO_COPY(Name) \
762 MOCHI_DECLARE_NO_MOVE(Name)
766#define MOCHI_DECLARE_MOVE_ONLY(Name) \
767 MOCHI_DECLARE_MOVE(Name); \
768 MOCHI_DECLARE_NO_COPY(Name)
773#define MOCHI_DECLARE_NO_ASSIGN(Name) \
774 Name& operator=(Name const&) = delete; \
775 Name& operator=(Name&&) = delete;
779#if MOCHI_COMPILER_MSVC
780#define MOCHI_EMPTY_BASE __declspec(empty_bases)
782#define MOCHI_EMPTY_BASE
789#if MOCHI_LANGUAGE_CPP
804#define MOCHI_CONCEPT(a) std::enable_if_t<a, superdex::ConceptMatch> = superdex::ConceptMatch::True
807#define MOCHI_CONCEPT_DEF(a) std::enable_if_t<a, superdex::ConceptMatch>
816#if MOCHI_LANGUAGE_CPP20
817#define MOCHI_LIKELY [[likely]]
818#define MOCHI_UNLIKELY [[unlikely]]
821#define MOCHI_UNLIKELY
828#if !(MOCHI_COMPILER_CUDA || MOCHI_COMPILER_MSVC || MOCHI_COMPILER_GCC || MOCHI_COMPILER_CLANG)
829#error "Unknown compiler"
832 MOCHI_PLATFORM_ANDROID || MOCHI_PLATFORM_LINUX || MOCHI_PLATFORM_MACOS || \
833 MOCHI_PLATFORM_WINDOWS)
834#error "Unknown platform"