
# TinyGPU backend: an eGPU through TinyGPU.app. NV and AMD both boot
# and run in C++, with no Python (../TinyGPU.md; TODO.md plan steps
# C13c and A2l).
#
# Prerequisites:
#   - macOS with TinyGPU.app installed in /Applications/
#   - nvcc and ptxas (CUDA 12.8) at build time, for the kernels header and the
#     C++ runtime's embedded cubins
#   - for AMD, comgr (libamd_comgr) at build time, for the embedded HSACOs
#
# Build:  cmake -DBUILD_TINYGPU=ON ..

add_definitions(-DFW_TINYGPU)
enable_language(ASM)  # ../kernels/BeagleTinyGPU_cubins.S
# Generated by ../CMakeLists.txt (TinyGPUCubins); under CMake 3.12's policies
# GENERATED does not carry across directories.
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../kernels/BeagleTinyGPU_cubins.S" PROPERTIES GENERATED TRUE
        OBJECT_DEPENDS "${TINYGPU_CUBINS}")  # the files it .incbin's (../CMakeLists.txt)

add_library(hmsbeagle-tinygpu SHARED
        ../BeagleGPUImpl.h
        ../BeagleGPUImpl.hpp
        ../GPUImplDefs.h
        ../GPUImplHelper.cpp
        ../GPUImplHelper.h
        ../GPUInterfaceTinyGPU.cpp
        ../GPUInterfaceTinyGPUAMD.cpp
        ../GPUInterfaceTinyGPUAMD.h
        ../GPUInterfaceTinyGPUNV.cpp
        ../GPUInterfaceTinyGPUNV.h
        ../TinyGPUTransport.h
        ../TinyGPUAMDTables.h
        ../TinyGPUAMDDispatch.h
        ../TinyGPUAMDProgram.h
        ../TinyGPUAMDRuntime.h
        ../TinyGPUAMDBootTables.h
        ../TinyGPUAMDReg.h
        ../TinyGPUAMDBoot.h
        ../TinyGPUAMDDevice.h
        ../TinyGPUNVDispatch.h
        ../TinyGPUElf.h
        ../TinyGPUNVProgram.h
        ../TinyGPUNVCubins.h
        ../TinyGPUNVTables.h
        ../KernelLauncher.cpp
        ../KernelLauncher.h
        ../KernelResource.cpp
        ../KernelResource.h
        ../TinyGPUPlugin.cpp
        ../TinyGPUPlugin.h
        ../Precision.h
        ../kernels/BeagleTinyGPU_cubins.S
        )

add_dependencies(hmsbeagle-tinygpu TinyGPUKernels)
add_dependencies(hmsbeagle-tinygpu TinyGPUCubins)
# the resource's card name and revision from the IORegistry (GPUInterfaceTinyGPU.cpp, GetDeviceName)
target_link_libraries(hmsbeagle-tinygpu "-framework IOKit" "-framework CoreFoundation")
# the plugin's status notes on stderr (TinyGPULog.h's TG_STATUS), which the test harness reads; off, it prints errors only
option(BEAGLE_TINYGPU_STATUS "Print the TinyGPU plugin's status notes on stderr (the test harness needs them)" OFF)
if(BEAGLE_TINYGPU_STATUS)
    target_compile_definitions(hmsbeagle-tinygpu PRIVATE BEAGLE_TINYGPU_STATUS)
endif()
if(BUILD_SPECTRAL)   # the spectral implementation: a second factory in this plugin, on the SPEC_ modules (TODO.md plan step S3.3)
    target_sources(hmsbeagle-tinygpu PRIVATE ../BeagleGPUSpectralImpl.h ../BeagleGPUSpectralImpl.hpp)
    target_compile_definitions(hmsbeagle-tinygpu PRIVATE BEAGLE_TINYGPU_SPECTRAL)
endif()
if(BUILD_FUSED)   # the TEST fused implementation: another factory in this plugin, on the standard modules, which then hold
    # kernelUpPartialsFused (fused-handoff/PLAN-fused-uppartials.md section 6)
    target_sources(hmsbeagle-tinygpu PRIVATE ../BeagleGPUFusedImpl.h ../BeagleGPUFusedImpl.hpp)
    target_compile_definitions(hmsbeagle-tinygpu PRIVATE BEAGLE_TINYGPU_FUSED)
endif()
if(TINYGPU_COMGR)   # the AMD C++ runtime's ahead-of-time HSACOs (../CMakeLists.txt, TODO.md plan step A1j)
    set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../kernels/BeagleTinyGPU_hsaco.S" PROPERTIES GENERATED TRUE
            OBJECT_DEPENDS "${TINYGPU_HSACOS}")
    target_sources(hmsbeagle-tinygpu PRIVATE ../kernels/BeagleTinyGPU_hsaco.S)
    target_compile_definitions(hmsbeagle-tinygpu PRIVATE TINYGPU_AMD_HSACO=1)
    add_dependencies(hmsbeagle-tinygpu TinyGPUHsaco)
endif()
# AMD path (GPUInterfaceTinyGPUAMD.cpp) compiles BEAGLE's existing
# kernel source via comgr's HIP language (STATUS.md AMD §18-19) -- see
# CMake_HIP/CMakeLists.txt and libhmsbeagle/GPU/CMakeLists.txt's
# BeagleOpenCL_kernels.h comment for why this depends on that target rather
# than defining its own generation rule.
add_dependencies(hmsbeagle-tinygpu HIPKernels)

install(TARGETS hmsbeagle-tinygpu
    DESTINATION ${BEAGLE_INSTALL_DIR}
    COMPONENT tinygpu
    )

# TODO.md plan steps C10 and C11: the crash guard the plugin spawns before its boot's first request to the GPU; the plugin
# looks for it next to itself. Since plan step A2k it keeps the AMD C++ boot's GPU too.
add_executable(beagle-tinygpu-guard ../tinygpu_guard.cpp ../TinyGPUNVGuard.h)
add_dependencies(hmsbeagle-tinygpu beagle-tinygpu-guard)
install(TARGETS beagle-tinygpu-guard
    DESTINATION ${BEAGLE_INSTALL_DIR}
    COMPONENT tinygpu
    )

SET_TARGET_PROPERTIES(hmsbeagle-tinygpu
    PROPERTIES
    SOVERSION "${BEAGLE_PLUGIN_VERSION_EXTENDED}"
    SUFFIX "${BEAGLE_PLUGIN_SUFFIX}"
    )

if(NOT MSVC)
	target_compile_options(hmsbeagle-tinygpu PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
endif(NOT MSVC)
