-
Notifications
You must be signed in to change notification settings - Fork 14
Add FORM output module for phlex product_store integration #177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 28 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
9b5550f
Skeleton of Phlex/FORM integration module
knoepfel 692a1ea
Merge remote-tracking branch 'origin/main' into barnali/form-integrat…
barnaliy 71c6034
Add FORM output module for phlex product persistence
barnaliy cfa3d5a
Change to form::experimental::product_with_name
barnaliy a9c7907
1. Remove mock_phlex from test dependencies (now using form::experime…
barnaliy a180834
Add test_helpers.hpp with createTypeMap implementation for FORM tests
barnaliy 8cf4609
Apply clang-format to FORM integration and test files
barnaliy 17ba271
Remove mock_phlex directory
barnaliy eeffe13
Apply cmake-format fixes
github-actions[bot] aadbe69
Remove phlex::experimental dependency from form_module (not needed in…
barnaliy bf8a58c
Merge phlexbot formatting changes
barnaliy 63e32b1
Remove phlex::experimental from form_module dependencies
barnaliy f68cf4d
Remove temporary comments and duplicate lines
barnaliy 7db2419
Add integration test for form_module plugin. This test exercises Form…
barnaliy f3ba8dd
Trivial comment removed
barnaliy bd19e1f
Apply cmake-format fixes
github-actions[bot] 2b24836
Make form_module a MODULE library
knoepfel 08925e8
Fix form_module build: add form library dependency and enable PIC. Re…
barnaliy a86fa3d
Fix test failure by adding missing 'sum' product configuration. The f…
barnaliy 5e18ba1
Add branch_name to sum product configuration. Still failing with miss…
barnaliy 2a4f1c2
fix: Register products in form_module constructor to resolve runtime …
barnaliy 3539c2e
fix: Add int type registration for sum product. Hardcoded product reg…
barnaliy 59d8e91
Fix: Could not locate library with specification 'source' error. Corr…
barnaliy 7fd6f3e
Apply cmake-format fixes
github-actions[bot] e62c3ab
form_test: switch from source to generate_layers
pcanal c6a1464
form: Properly store the TTree in its directory
pcanal 5278497
Implementing Peter's suggestion: switch from sprintf to snprintf
barnaliy a1d8125
Fixing...
barnaliy 9b49214
Form: register more supported type.
pcanal fdf681c
fix: Read products from config instead of hardcoding (addresses PC's …
barnaliy ec53af3
fix: Use simple array for products config per Kyle's suggestion
barnaliy d6ae99a
Commit from GitHub Actions (Clang-Format Fix)
github-actions[bot] 56239b3
fix: Pass by const reference
barnaliy 1e13a7e
Merge branch 'main' into barnali/form-integration-work
knoepfel 45eae1e
Do not move products_to_save vector
knoepfel cd323e2
Adjust PHLEX_PLUGIN_PATH for form_module test
knoepfel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| #include "phlex/model/product_store.hpp" | ||
| #include "phlex/model/products.hpp" | ||
| #include "phlex/module.hpp" | ||
|
|
||
| // FORM headers - these need to be available via CMake configuration | ||
| // need to set up the build system to find these headers | ||
| #include "form/config.hpp" | ||
| #include "form/form.hpp" | ||
| #include "form/technology.hpp" | ||
|
|
||
| #include <iostream> | ||
|
|
||
| namespace { | ||
|
|
||
| class FormOutputModule { | ||
| public: | ||
| FormOutputModule(std::shared_ptr<form::experimental::product_type_names> type_map, | ||
| std::string output_file, | ||
| int technology) : | ||
| m_type_map(type_map), m_output_file(std::move(output_file)), m_technology(technology) | ||
| { | ||
| std::cout << "FormOutputModule initialized\n"; | ||
| std::cout << " Output file: " << m_output_file << "\n"; | ||
| std::cout << " Technology: " << m_technology << "\n"; | ||
|
|
||
| // Build FORM configuration | ||
| form::experimental::config::output_item_config output_cfg; | ||
| form::experimental::config::tech_setting_config tech_cfg; | ||
|
|
||
| // FIXME: Temporary solution to accommodate Phlex limitation. | ||
| // Eventually, Phlex will communicate to FORM which products will be written | ||
| // before executing any algorithms | ||
|
|
||
| // Temp. Sol for Phlex Prototype 0.1 | ||
| // Register products that will be written | ||
| // Register "sum" product with output file and technology | ||
| output_cfg.addItem("sum", m_output_file, m_technology); | ||
knoepfel marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| std::cout << " Registered product 'sum' with FORM\n"; | ||
|
|
||
| // Initialize FORM interface | ||
| m_form_interface = | ||
| std::make_unique<form::experimental::form_interface>(type_map, output_cfg, tech_cfg); | ||
| } | ||
|
|
||
| // This method is called by Phlex - signature must be: void(product_store const&) | ||
| void save_data_products(phlex::experimental::product_store const& store) | ||
| { | ||
| // Check if store is empty - smart way, check store not products vector | ||
| if (store.empty()) { | ||
| return; | ||
| } | ||
|
|
||
| // STEP 1: Extract metadata from Phlex's product_store | ||
|
|
||
| // Extract creator (algorithm name) | ||
| std::string creator = store.source(); | ||
knoepfel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Extract segment ID (partition) - extract once for entire store | ||
| std::string segment_id = store.id()->to_string(); | ||
|
|
||
| std::cout << "\n=== FormOutputModule::save_data_products ===\n"; | ||
| std::cout << "Creator: " << creator << "\n"; | ||
| std::cout << "Segment ID: " << segment_id << "\n"; | ||
| std::cout << "Number of products: " << store.size() << "\n"; | ||
|
|
||
| // STEP 2: Convert each Phlex product to FORM format | ||
|
|
||
| // Collect all products for writing | ||
| std::vector<form::experimental::product_with_name> products; | ||
|
|
||
| // Reserve space for efficiency - avoid reallocations | ||
| products.reserve(store.size()); | ||
|
|
||
| // Iterate through all products in the store | ||
| for (auto const& [product_name, product_ptr] : store) { | ||
| // product_name: "tracks" (from the map key) | ||
| // product_ptr: pointer to the actual product data | ||
|
|
||
| std::cout << " Product: " << product_name << "\n"; | ||
|
|
||
| // Create FORM product with metadata | ||
| products.emplace_back(product_name, // label, from map key | ||
| product_ptr->address(), // data, from phlex product_base | ||
| product_ptr->type() // type, from phlex product_base | ||
| ); | ||
| } | ||
|
|
||
| // STEP 3: Send everything to FORM for persistence | ||
|
|
||
| // Write all products to FORM | ||
| // Pass segment_id once for entire collection (not duplicated in each product) | ||
| // No need to check if products is empty - already checked store.empty() above | ||
| m_form_interface->write(creator, segment_id, products); | ||
| std::cout << "Wrote " << products.size() << " products to FORM\n"; | ||
| } | ||
|
|
||
| private: | ||
| std::shared_ptr<form::experimental::product_type_names> m_type_map; | ||
| std::string m_output_file; | ||
| int m_technology; | ||
| std::unique_ptr<form::experimental::form_interface> m_form_interface; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| PHLEX_EXPERIMENTAL_REGISTER_ALGORITHMS(m, config) | ||
| { | ||
| std::cout << "Registering FORM output module...\n"; | ||
|
|
||
| // Create type map | ||
| auto type_map = std::make_shared<form::experimental::product_type_names>(); | ||
|
|
||
| // Register the int type for sum product | ||
| type_map->names[std::type_index(typeid(int))] = "int"; | ||
|
|
||
| // TODO: Register product types | ||
| // This needs to be populated with actual types your application uses | ||
| // Example: | ||
| // type_map->names[std::type_index(typeid(TrackData))] = "TrackData"; | ||
| // type_map->names[std::type_index(typeid(HitCollection))] = "HitCollection"; | ||
|
|
||
| // Extract configuration from Phlex config | ||
| std::string output_file = config.get<std::string>("output_file", "output.root"); | ||
| std::string tech_string = config.get<std::string>("technology", "ROOT_TTREE"); | ||
|
|
||
| std::cout << "Configuration:\n"; | ||
| std::cout << " output_file: " << output_file << "\n"; | ||
| std::cout << " technology: " << tech_string << "\n"; | ||
|
|
||
| // Map Phlex config string to FORM technology constant | ||
| int technology = form::technology::ROOT_TTREE; // default | ||
|
|
||
| if (tech_string == "ROOT_TTREE") { | ||
| technology = form::technology::ROOT_TTREE; | ||
| } else if (tech_string == "ROOT_RNTUPLE") { | ||
| technology = form::technology::ROOT_RNTUPLE; | ||
| } else if (tech_string == "HDF5") { | ||
| technology = form::technology::HDF5; | ||
| } else { | ||
| throw std::runtime_error("Unknown technology: " + tech_string); | ||
| } | ||
|
|
||
| // Phlex needs an OBJECT | ||
| // Create the FORM output module | ||
| auto form_output = m.make<FormOutputModule>(type_map, output_file, technology); | ||
|
|
||
| // Phlex needs a MEMBER FUNCTION to call | ||
| // Register the callback that Phlex will invoke | ||
| form_output.output("save_data_products", &FormOutputModule::save_data_products); | ||
|
|
||
| std::cout << "FORM output module registered successfully\n"; | ||
| } | ||
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.