Files
Ayzen b88d704126 Port the SAR3D background gate, CLEAN and object boxes from Multi_depthnorm_clean
- BG_GATE_ENABLE: frame peak over its median background (sar3d_background); the
  GUI scales the frame with bg_gate_gain and its cloud threshold.
- SAR_CLEAN_ENABLE: CLEAN of a one-frame aperture on a 4x10x4 cm search grid over
  the whole scene; objects in their own scale (sar3d_objects).
- SAR_MARK_ENABLE: boxes by class around object groups (sar3d_marks), with the
  legend under the views.
- SAR_VOXEL_M as three steps X/Y/Z with the notebook defaults 0.025/0.02/0.02.
- GPU backend: image/download/load/project API, per-plane block reduction for the
  maximum, depth gate without FMA; sar3d host code built with -ffp-contract=off.
- References regenerated from notebook cells 1 and 5, with new CLEAN scenes and a
  synthetic box-rule case; docs updated.
2026-10-16 12:08:57 +03:00

198 lines
10 KiB
Makefile

CXX := g++
PYTHON ?= .venv/bin/python
CXXFLAGS := -std=c++20 -O2 -Wall -Wextra -Wpedantic -pthread -MMD -MP
LDFLAGS := -pthread -lrt
BUILD_DIR := build
BIN_DIR := $(BUILD_DIR)/bin
# --- CUDA for the sar3d processor (optional). Its kernels are compiled at run
# time by NVRTC and launched through the CUDA driver API, so no nvcc is needed:
# only nvrtc.h, cuda.h, libnvrtc and the NVIDIA driver's libcuda. Headers and
# libnvrtc come from the pip nvidia-cuda-* packages in .venv (requirements.txt,
# x86_64) or from a system toolkit in /usr/local/cuda (Jetson). Without them
# data_processor still builds; selecting sar3d shows a CUDA warning.
CUDA_ROOTS := $(wildcard $(CURDIR)/.venv/lib/python3*/site-packages/nvidia/*) /usr/local/cuda
CUDA_NVRTC_HEADER := $(firstword $(wildcard $(addsuffix /include/nvrtc.h,$(CUDA_ROOTS))))
CUDA_DRIVER_HEADER := $(firstword $(wildcard $(addsuffix /include/cuda.h,$(CUDA_ROOTS))))
CUDA_NVRTC_LIB := $(firstword $(wildcard $(addsuffix /lib/libnvrtc.so.*,$(CUDA_ROOTS)) $(addsuffix /lib64/libnvrtc.so.*,$(CUDA_ROOTS))))
CUDA_DRIVER_LIB := $(firstword $(wildcard /usr/lib/*-linux-gnu/libcuda.so.1 /usr/lib/*-linux-gnu/nvidia/libcuda.so.1 /usr/lib64/libcuda.so.1))
ifneq ($(and $(CUDA_NVRTC_HEADER),$(CUDA_DRIVER_HEADER),$(CUDA_NVRTC_LIB),$(CUDA_DRIVER_LIB)),)
SAR3D_CXXFLAGS := -DSAR3D_WITH_CUDA $(addprefix -I,$(sort $(dir $(CUDA_NVRTC_HEADER) $(CUDA_DRIVER_HEADER))))
# The rpath lets data_processor find the pip libnvrtc without LD_LIBRARY_PATH.
SAR3D_LDFLAGS := $(CUDA_NVRTC_LIB) $(CUDA_DRIVER_LIB) -Wl,-rpath,$(dir $(CUDA_NVRTC_LIB))
endif
# Rewritten only when the CUDA setup changes, so installing (or removing) CUDA
# rebuilds the sar3d GPU code instead of keeping a stale build.
SAR3D_CUDA_STAMP := $(BUILD_DIR)/sar3d_cuda.flags
SAR3D_HOST_FLAGS := -ffp-contract=off
$(shell mkdir -p $(BUILD_DIR) && echo '$(SAR3D_CXXFLAGS) $(SAR3D_LDFLAGS)' | cmp -s - $(SAR3D_CUDA_STAMP) || echo '$(SAR3D_CXXFLAGS) $(SAR3D_LDFLAGS)' > $(SAR3D_CUDA_STAMP))
INCLUDES := \
-Idata_acq_and_processing/common_cpp/ipc/include \
-Idata_acq_and_processing/common_cpp/config/include \
-Idata_acq_and_processing/third_party \
-Idata_acq_and_processing/third_party/eigen \
-Idata_acq_and_processing/preprocessing/bundles/include \
-Idata_acq_and_processing/preprocessing/data_preprocessor/include \
-Idata_acq_and_processing/processing/processors/include \
-Idata_acq_and_processing/processing/data_processor/include \
-Idata_acq_and_processing/processing/locator/include
COMMON_SOURCES := \
data_acq_and_processing/common_cpp/ipc/src/shm_ring.cpp \
data_acq_and_processing/common_cpp/ipc/src/shared_types.cpp \
data_acq_and_processing/common_cpp/config/src/run_config.cpp
PREPROC_SOURCES := \
data_acq_and_processing/preprocessing/bundles/src/channel_bundle_support.cpp \
data_acq_and_processing/preprocessing/data_preprocessor/src/data_preprocessor.cpp \
data_acq_and_processing/preprocessing/data_preprocessor/src/main.cpp
LOCATOR_SOURCES := \
data_acq_and_processing/processing/locator/src/payload_builder.cpp \
data_acq_and_processing/processing/locator/src/tcp_server.cpp
PROCESSOR_SOURCES := \
data_acq_and_processing/processing/processors/src/bscan_processor.cpp \
data_acq_and_processing/processing/processors/src/gpr_processor.cpp \
data_acq_and_processing/processing/processors/src/passthrough_processor.cpp \
data_acq_and_processing/processing/processors/src/sar3d_processor.cpp \
data_acq_and_processing/processing/processors/src/sar3d_clean.cpp \
data_acq_and_processing/processing/processors/src/sar3d_gpu.cpp \
data_acq_and_processing/processing/data_processor/src/processing_live_config.cpp \
data_acq_and_processing/processing/data_processor/src/data_processor.cpp \
data_acq_and_processing/processing/data_processor/src/main.cpp \
$(LOCATOR_SOURCES)
# RadioPhotonic radar (RPH) collector: application-owned L-Card E-502 acquisition binary. It loads the
# proprietary libx502api/libe502api at runtime via dlopen, so it builds anywhere
# from the vendored headers alone and only needs those libraries present at run
# time. Built on demand (not part of `all`) for radar.model == rph_radar.
RPH_COLLECTOR_DIR := data_acq_and_processing/rph_radar_collector
# The collector drives H7992 switches from the validated JSON supplied by Python.
RPH_COLLECTOR_INCLUDES := \
-I$(RPH_COLLECTOR_DIR)/include \
-I$(RPH_COLLECTOR_DIR)/vendor/lcard \
-Idata_acq_and_processing/common_cpp/ipc/include \
-Idata_acq_and_processing/common_cpp/config/include \
-Idata_acq_and_processing/common_cpp/hardware/include \
-Idata_acq_and_processing/processing/locator/include \
-Idata_acq_and_processing/third_party
RPH_COLLECTOR_LDFLAGS := -pthread -ldl -lutil
# Collector sources, including the shared H7992 driver. These
# are compiled into a private build/rph/ tree (see rule below) so they never
# collide with pipeline objects, which use different include paths.
RPH_COLLECTOR_SOURCES := \
$(RPH_COLLECTOR_DIR)/src/main.cpp \
$(RPH_COLLECTOR_DIR)/src/tty_protocol_writer.cpp \
data_acq_and_processing/common_cpp/hardware/src/h7992_minimal_driver.cpp
PREPROCESSOR_OBJS := $(addprefix $(BUILD_DIR)/,$(COMMON_SOURCES:.cpp=.o) $(PREPROC_SOURCES:.cpp=.o))
DATA_PROCESSOR_OBJS := $(addprefix $(BUILD_DIR)/,$(COMMON_SOURCES:.cpp=.o) $(PROCESSOR_SOURCES:.cpp=.o))
RPH_BUILD_DIR := $(BUILD_DIR)/rph
RPH_COLLECTOR_OBJS := $(addprefix $(RPH_BUILD_DIR)/,$(RPH_COLLECTOR_SOURCES:.cpp=.o))
DEPFILES := $(sort $(PREPROCESSOR_OBJS:.o=.d) $(DATA_PROCESSOR_OBJS:.o=.d) $(RPH_COLLECTOR_OBJS:.o=.d))
NATIVE_TEST_SOURCES := $(COMMON_SOURCES) $(LOCATOR_SOURCES) \
data_acq_and_processing/tests/native_regressions.cpp \
data_acq_and_processing/processing/data_processor/src/processing_live_config.cpp \
$(filter-out %/main.cpp,$(PREPROC_SOURCES)) \
$(RPH_COLLECTOR_DIR)/src/tty_protocol_writer.cpp \
data_acq_and_processing/common_cpp/hardware/src/h7992_minimal_driver.cpp
NATIVE_BUILD_DIR := $(BUILD_DIR)/native_tests
NATIVE_TEST_OBJS := $(addprefix $(NATIVE_BUILD_DIR)/,$(NATIVE_TEST_SOURCES:.cpp=.o))
NATIVE_CXXFLAGS := $(CXXFLAGS) -O1 -g $(if $(NATIVE_SANITIZERS),-fsanitize=$(NATIVE_SANITIZERS) -fno-omit-frame-pointer)
NATIVE_FLAGS_STAMP := $(NATIVE_BUILD_DIR)/compiler.flags
$(shell mkdir -p $(NATIVE_BUILD_DIR) && echo '$(NATIVE_CXXFLAGS)' | cmp -s - $(NATIVE_FLAGS_STAMP) || echo '$(NATIVE_CXXFLAGS)' > $(NATIVE_FLAGS_STAMP))
DEPFILES += $(NATIVE_TEST_OBJS:.o=.d) $(RPH_BUILD_DIR)/data_acq_and_processing/tests/collector_regressions.d
TARGETS := \
$(BIN_DIR)/data_preprocessor \
$(BIN_DIR)/data_processor
.PHONY: all clean rph_radar_collector check-native check-sar3d check-gpr
all: $(TARGETS)
rph_radar_collector: $(BIN_DIR)/rph_radar_collector
check-native: $(NATIVE_BUILD_DIR)/native_regressions $(BIN_DIR)/collector_regressions $(NATIVE_BUILD_DIR)/rph_sdk/libx502api.so
LD_LIBRARY_PATH=$(abspath $(NATIVE_BUILD_DIR)/rph_sdk) $(BIN_DIR)/collector_regressions
$(NATIVE_BUILD_DIR)/native_regressions run_config_examples/run_config_simulator.example.json
BACKPROJECTION_TEST_SOURCES := data_acq_and_processing/tests/backprojection_fixture.cpp \
data_acq_and_processing/common_cpp/ipc/src/shared_types.cpp \
data_acq_and_processing/processing/processors/src/sar3d_processor.cpp \
data_acq_and_processing/processing/processors/src/sar3d_clean.cpp \
data_acq_and_processing/processing/processors/src/sar3d_gpu.cpp \
data_acq_and_processing/processing/processors/src/gpr_processor.cpp
BACKPROJECTION_TEST_OBJS := $(addprefix $(NATIVE_BUILD_DIR)/,$(BACKPROJECTION_TEST_SOURCES:.cpp=.o))
DEPFILES += $(BACKPROJECTION_TEST_OBJS:.o=.d)
# The sar3d processor on the real CUDA backend against the notebook reference; without a
# usable GPU the test checks the warning and the box rules and skips the rest.
check-sar3d: $(NATIVE_BUILD_DIR)/backprojection_fixture
BACKPROJECTION_FIXTURE="$(abspath $<)" $(PYTHON) data_acq_and_processing/tests/test_backprojection.py Sar3dTest
check-gpr: $(NATIVE_BUILD_DIR)/backprojection_fixture
BACKPROJECTION_FIXTURE="$(abspath $<)" $(PYTHON) data_acq_and_processing/tests/test_backprojection.py GprTest
$(NATIVE_BUILD_DIR)/backprojection_fixture: $(BACKPROJECTION_TEST_OBJS)
$(CXX) $(NATIVE_CXXFLAGS) $^ -o $@ $(LDFLAGS) $(SAR3D_LDFLAGS)
$(NATIVE_BUILD_DIR)/data_acq_and_processing/processing/processors/src/sar3d_gpu.o: NATIVE_CXXFLAGS += $(SAR3D_CXXFLAGS)
$(NATIVE_BUILD_DIR)/data_acq_and_processing/processing/processors/src/sar3d_%.o: NATIVE_CXXFLAGS += $(SAR3D_HOST_FLAGS)
$(NATIVE_BUILD_DIR)/data_acq_and_processing/processing/processors/src/sar3d_gpu.o: $(SAR3D_CUDA_STAMP)
$(NATIVE_BUILD_DIR)/native_regressions: $(NATIVE_TEST_OBJS)
$(CXX) $(NATIVE_CXXFLAGS) $^ -o $@ $(LDFLAGS) -lutil
$(NATIVE_BUILD_DIR)/%.o: %.cpp $(NATIVE_FLAGS_STAMP)
@mkdir -p $(dir $@)
$(CXX) $(NATIVE_CXXFLAGS) $(INCLUDES) -Idata_acq_and_processing/common_cpp/hardware/include -I$(RPH_COLLECTOR_DIR)/include -c $< -o $@
$(BIN_DIR)/data_preprocessor: $(PREPROCESSOR_OBJS)
@mkdir -p $(BIN_DIR)
$(CXX) $(PREPROCESSOR_OBJS) -o $@ $(LDFLAGS)
$(BIN_DIR)/data_processor: $(DATA_PROCESSOR_OBJS) $(SAR3D_CUDA_STAMP)
@mkdir -p $(BIN_DIR)
$(CXX) $(DATA_PROCESSOR_OBJS) -o $@ $(LDFLAGS) $(SAR3D_LDFLAGS)
$(if $(SAR3D_LDFLAGS),,@echo "note: CUDA not found, selecting sar3d will show a warning")
$(BUILD_DIR)/data_acq_and_processing/processing/processors/src/sar3d_gpu.o: CXXFLAGS += $(SAR3D_CXXFLAGS)
$(BUILD_DIR)/data_acq_and_processing/processing/processors/src/sar3d_gpu.o: $(SAR3D_CUDA_STAMP)
# The sar3d host code breaks the same ties as NumPy (grid corners on the depth gate, range
# rings), so it is not contracted into fused multiply-adds where the target has them.
$(BUILD_DIR)/data_acq_and_processing/processing/processors/src/sar3d_%.o: CXXFLAGS += $(SAR3D_HOST_FLAGS)
# Keep source-relative paths so moving a source also replaces its dependencies.
$(RPH_BUILD_DIR)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(RPH_COLLECTOR_INCLUDES) -c $< -o $@
$(RPH_BUILD_DIR)/data_acq_and_processing/tests/collector_regressions.o: data_acq_and_processing/tests/collector_regressions.cpp
$(NATIVE_BUILD_DIR)/rph_sdk/libx502api.so: data_acq_and_processing/tests/rph_sdk_fixture.cpp
@mkdir -p $(@D)
$(CXX) -std=c++20 -shared -fPIC -I$(RPH_COLLECTOR_DIR)/vendor/lcard $< -o $@
ln -sf libx502api.so $(@D)/libe502api.so
$(BIN_DIR)/collector_regressions: $(RPH_BUILD_DIR)/data_acq_and_processing/tests/collector_regressions.o $(filter-out %/main.o,$(RPH_COLLECTOR_OBJS))
@mkdir -p $(BIN_DIR)
$(CXX) $^ -o $@ $(RPH_COLLECTOR_LDFLAGS)
$(BIN_DIR)/rph_radar_collector: $(RPH_COLLECTOR_OBJS)
@mkdir -p $(BIN_DIR)
$(CXX) $(RPH_COLLECTOR_OBJS) -o $@ $(RPH_COLLECTOR_LDFLAGS)
$(BUILD_DIR)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
-include $(DEPFILES)
clean:
rm -rf $(BUILD_DIR)