diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index f57b58b6..6c3ad3c0 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -13,6 +13,9 @@ target_link_libraries(HDF5DatasetWriteTest JFJochWriter CommonFunctions) ADD_EXECUTABLE(DataAnalysisPerfTest DataAnalysisPerfTest.cpp) TARGET_LINK_LIBRARIES(DataAnalysisPerfTest ImageAnalysis JFJochWriter CommonFunctions) +ADD_EXECUTABLE(RadialIntegrationCPUTest RadialIntegrationCPUTest.cpp) +TARGET_LINK_LIBRARIES(RadialIntegrationCPUTest ImageAnalysis JFJochWriter CommonFunctions) + ADD_EXECUTABLE(PreviewTest PreviewTest.cpp) TARGET_LINK_LIBRARIES(PreviewTest JFJochWriter CommonFunctions) diff --git a/tools/RadialIntegrationCPUTest.cpp b/tools/RadialIntegrationCPUTest.cpp new file mode 100644 index 00000000..b9442f9f --- /dev/null +++ b/tools/RadialIntegrationCPUTest.cpp @@ -0,0 +1,89 @@ +// Copyright (2019-2022) Paul Scherrer Institute +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +#include "../image_analysis/RadialIntegration.h" +#include "../common/Logger.h" +#include "../writer/HDF5Objects.h" + +Logger logger{"RadialIntegrationCPUTest"}; + +void RunRadialIntegrationThread(RadialIntegration* integration, + int16_t* image, size_t nimages, + size_t image0, size_t stride, + size_t npixel) { + for (size_t i = image0; i < nimages; i += stride) + integration->ProcessOneImage(image + i * npixel, npixel); +} + +auto TestRadialIntegration(const DiffractionExperiment &experiment, + int16_t* image, size_t nimages, + uint32_t nthreads, + uint32_t pixel_split) { + uint32_t nredo = 5; + RadialIntegrationMapping mapping(experiment); + std::unique_ptr integration; + + if (pixel_split == 1) + integration = std::make_unique(mapping); + else + integration = std::make_unique(mapping.GetPixelToBinMappingSplitTo4(), + mapping.GetBinNumber(), 4); + + std::vector result; + + auto start_time = std::chrono::system_clock::now(); + for (int redo = 0; redo < nredo; redo++) { + std::vector> futures; + for (int i = 0; i < nthreads; i++) { + futures.emplace_back(std::async(std::launch::async, &RunRadialIntegrationThread, + integration.get(), image, nimages, + i, nthreads, + experiment.GetPixelsNum())); + } + for (auto &f: futures) + f.get(); + } + auto end_time = std::chrono::system_clock::now(); + auto elapsed = std::chrono::duration_cast(end_time - start_time); + + return elapsed.count() / (1000.0 * (double) nimages * nredo); +} + +int main(int argc, char **argv) { + if (argc > 3) { + logger.Info("Usage: ./DataAnalysisPerfTest {} {}"); + exit(EXIT_FAILURE); + } + + uint32_t nthreads = 1; + if (argc >= 2) + nthreads = atol(argv[1]); + + uint64_t nimages = 100; + if (argc == 3) + nimages = atol(argv[2]); + + if ((nthreads <= 0) || (nimages <= 0)) { + std::cerr << "Error in input parameters" << std::endl; + exit(EXIT_FAILURE); + } + + DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); + + logger.Info("Number of threads: {}", nthreads); + logger.Info("Number of images in the dataset: {}", nimages); + + x.Mode(DetectorMode::Conversion); + + std::vector image_conv ( nimages * x.GetPixelsNum(), 30); + + x.BeamX_pxl(1090).BeamY_pxl(1136).DetectorDistance_mm(75).PhotonEnergy_keV(WVL_1A_IN_KEV); + std::vector one_byte_mask(x.GetPixelsNum(), 1); + + logger.Info("{:30s} {:8.1f} ms/image", "Radial int. pxlspl 1 (CPU)", + TestRadialIntegration(x, image_conv.data(), nimages, nthreads, 1)); + logger.Info("{:30s} {:8.1f} ms/image", "Radial int. pxlspl 2 (CPU)", + TestRadialIntegration(x, image_conv.data(), nimages, nthreads, 4)); +}