Skip to content
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

cmake release dep version overrides #920

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

PhilipDeegan
Copy link
Member

@PhilipDeegan PhilipDeegan commented Oct 29, 2024

Summary by CodeRabbit

  • New Features

    • Added functionality to dump and load PHAREDict objects, enhancing data persistence in the data provider system.
    • Introduced a new hierarchical dictionary structure for managing parameters related to ions and electromagnetic properties.
    • Updated versioning for several dependencies to improve compatibility and stability.
  • Bug Fixes

    • Resolved issues with hardcoded version values in CMake configurations for various dependencies.
  • Documentation

    • Enhanced documentation on the new dump and load methods for PHAREDictHandler.
  • Tests

    • Added tests for the new dictionary creation, serialization, and validation processes.

Copy link

coderabbitai bot commented Oct 29, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces several modifications to CMake configuration files and source code to enhance version management and functionality. Key changes include the introduction of conditional checks for version variables in CMake files for cppdict, highfive, pybind, and samrai, allowing for default values if not previously defined. Additionally, new methods for dumping and loading PHAREDict objects are added in the data_provider.hpp file, along with a new test file phare_dict.cpp that validates these functionalities.

Changes

File Change Summary
res/cmake/dep/cppdict.cmake - Added variable PHARE_CPPDICT_VERION with default "superserial".
- Commented out old CPPDICT_VERSION and updated repository source in phare_github_get_or_update.
res/cmake/dep/highfive.cmake - Added variable PHARE_HIGHFIVE_VERSION with default "master" if not defined.
res/cmake/dep/pybind.cmake - Added variable PHARE_PYBIND11_VERSION with default "master" if not defined.
res/cmake/dep/samrai.cmake - Added variable PHARE_SAMRAI_VERSION with default "develop" if not defined.
res/cmake/release.cmake - Added version variables: PHARE_SAMRAI_VERSION to "v4.3.0", PHARE_PYBIND11_VERSION to "v2.13.6", PHARE_HIGHFIVE_VERSION to "v2.10.0", PHARE_CPPDICT_VERION to "v1.0.0".
src/initializer/data_provider.hpp - Added methods for dumping and loading PHAREDict objects: dump_phare_dict, load_phare_dict, and corresponding methods in PHAREDictHandler.
tests/initializer/phare_dict.cpp - Introduced createDict() function for hierarchical dictionary creation and validation, along with a main() function for testing serialization and deserialization.

Possibly related PRs

  • simpler dep handling + versions #887: The changes in this PR involve modifications to the cppdict dependency management in CMake, which directly relates to the updates made in the main PR regarding the cppdict project configuration.

Suggested reviewers

  • nicolasaunai

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Outside diff range and nitpick comments (5)
res/cmake/dep/pybind.cmake (1)

12-14: Consider using a specific version tag for reproducible builds.

Using "master" as the default version can lead to inconsistent builds as it points to different commits over time. Consider using a specific version tag as the default.

Apply this diff to set a specific version:

  if(NOT DEFINED PHARE_PYBIND11_VERSION)
-   SET(PHARE_PYBIND11_VERSION "master")
+   SET(PHARE_PYBIND11_VERSION "v2.13.6")  # Or another stable version
  endif()
res/cmake/dep/samrai.cmake (1)

13-16: Consider adding a brief comment explaining the version override mechanism.

It would be helpful to add a comment explaining that this version can be overridden (e.g., in release.cmake) and what the "develop" version implies.

+# PHARE_SAMRAI_VERSION can be overridden externally (e.g., in release.cmake)
+# Defaults to "develop" for development builds
 if(NOT DEFINED PHARE_SAMRAI_VERSION)
   SET(PHARE_SAMRAI_VERSION "develop")
 endif()
src/initializer/data_provider.hpp (1)

Line range hint 57-100: Consider adding serialization format versioning.

For long-term maintainability and backward compatibility, consider adding version information to the serialized format. This will help manage future schema changes and ensure proper migration paths.

Key considerations:

  1. Add a version field to the serialized format
  2. Document the serialization format
  3. Consider providing migration utilities for future format changes
  4. Add validation for the deserialized data
tests/initializer/phare_dict.cpp (2)

84-85: Consider extracting magic numbers as named constants.

The temperature value 0.12 should be defined as a named constant for better maintainability and clarity.

constexpr double ELECTRON_TEMPERATURE = 0.12;
// ...
dict["electrons"]["pressure_closure"]["Te"] = ELECTRON_TEMPERATURE;

96-96: Remove commented code.

The commented line should be removed if it's no longer needed.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e61b34c and 2f32ac1.

📒 Files selected for processing (7)
  • res/cmake/dep/cppdict.cmake (1 hunks)
  • res/cmake/dep/highfive.cmake (1 hunks)
  • res/cmake/dep/pybind.cmake (1 hunks)
  • res/cmake/dep/samrai.cmake (1 hunks)
  • res/cmake/release.cmake (1 hunks)
  • src/initializer/data_provider.hpp (3 hunks)
  • tests/initializer/phare_dict.cpp (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • res/cmake/release.cmake
🧰 Additional context used
📓 Path-based instructions (1)
src/initializer/data_provider.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

🔇 Additional comments (8)
res/cmake/dep/cppdict.cmake (1)

8-9: Verify the repository change and version selection

The change from LaboratoryOfPlasmaPhysics/cppdict to PhilipDeegan/cppdict raises several concerns:

  1. Moving from an organizational to a personal repository might impact stability and maintenance
  2. The version change from "master" to "superserial" needs justification
  3. Long-term maintenance implications should be considered

Please provide rationale for these changes and confirm if this is a temporary solution or permanent change.

Let's verify the repository and version:

✅ Verification successful

Let me gather more information about the version changes and the relationship between these repositories.


Repository change appears to be a collaborative effort with proper maintenance

Based on the verification results, the concerns about the repository change can be addressed:

  1. The personal fork (PhilipDeegan/cppdict) is actively maintained and the author (Philip Deegan) is actually a contributor to the original repository, as evidenced by his commits in both repositories.
  2. The "superserial" branch contains specific improvements tested with PHARE, as shown in the commit message "tested with phare dict" and includes serialization enhancements.
  3. The changes are well-structured, with proper code organization (moving serialization to a separate header) and added test coverage.
  • The original repository badges and CI infrastructure are preserved in the fork
  • The code quality and maintenance standards appear to be maintained
  • The version change to "superserial" adds needed functionality for PHARE
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the personal fork exists and contains the required version
gh repo view PhilipDeegan/cppdict 2>/dev/null || echo "Repository not found"
gh api repos/PhilipDeegan/cppdict/branches/superserial 2>/dev/null || echo "Branch not found"

# Check if there are any other dependencies still using the original repository
rg -l "LaboratoryOfPlasmaPhysics/cppdict" res/cmake/

Length of output: 7873


Script:

#!/bin/bash
# Check the commit history and differences between repositories
gh api repos/LaboratoryOfPlasmaPhysics/cppdict/branches/master 2>/dev/null || echo "Original repo branch not found"

# Check for version references
rg "PHARE_CPPDICT_VERION" -A 1 -B 1

# Check if there are any specific changes in the superserial branch
gh api repos/PhilipDeegan/cppdict/commits/superserial 2>/dev/null || echo "Cannot fetch commit info"

Length of output: 32322

res/cmake/dep/highfive.cmake (1)

12-12: LGTM! Good use of the configurable version variable.

The change properly integrates the new version variable, maintaining functionality while adding flexibility for version management.

res/cmake/dep/samrai.cmake (1)

14-16: LGTM! Good approach to version management.

The introduction of PHARE_SAMRAI_VERSION with a default value provides good flexibility for version control while maintaining a sensible default for development.

src/initializer/data_provider.hpp (2)

14-14: LGTM!

The serializer include is correctly placed and follows the include order convention.


93-99: ⚠️ Potential issue

Address thread safety and ownership concerns in PHAREDictHandler methods.

Several issues need attention:

  1. The singleton pattern with static methods needs thread safety guarantees
  2. The load method's ownership semantics are unclear
  3. The comment "// ?" suggests implementation uncertainty

Consider this safer implementation:

-    void dump(std::string const& filename) const { dump_phare_dict(*phareDict, filename); }
+    void dump(std::string const& filename) const
+    {
+        if (!phareDict) {
+            throw std::runtime_error("Cannot dump: dictionary not initialized");
+        }
+        dump_phare_dict(*phareDict, filename);
+    }

-    static auto& load(std::string const& filename)
+    static PHAREDict& load(std::string const& filename)
     {
-        INSTANCE().phareDict = std::make_unique<PHAREDict>();       // reset
-        return (*INSTANCE().phareDict = load_phare_dict(filename)); // ?
+        auto& instance = INSTANCE();
+        std::lock_guard<std::mutex> lock(instance.mutex_);  // Add mutex_ as class member
+        instance.phareDict = std::make_unique<PHAREDict>(load_phare_dict(filename));
+        return *instance.phareDict;
     }

Let's verify if there are any other usages of these methods that might be affected:

tests/initializer/phare_dict.cpp (3)

1-11: LGTM: Headers and namespace usage are appropriate.

The includes and type aliases are well-organized and properly scoped for the test requirements.


42-44: Verify the identical charge configuration.

Both populations are configured with charge -1.0, which seems unusual as alpha particles typically have a different charge than protons.

Please confirm if this is intentional or if it needs adjustment.

Also applies to: 72-74


107-107: Document serialization limitations.

The comment indicates that x_component is not serializable, but this limitation should be properly documented in the relevant API documentation.

Comment on lines +3 to +4
if(NOT DEFINED PHARE_CPPDICT_VERION)
SET(PHARE_CPPDICT_VERION "superserial")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix typo in variable name: VERION → VERSION

There's a critical typo in the variable name PHARE_CPPDICT_VERION which should be PHARE_CPPDICT_VERSION. This typo needs to be fixed to maintain consistency and prevent potential issues.

Apply this diff to fix the typo:

-if(NOT DEFINED PHARE_CPPDICT_VERION)
-  SET(PHARE_CPPDICT_VERION "superserial")
+if(NOT DEFINED PHARE_CPPDICT_VERSION)
+  SET(PHARE_CPPDICT_VERSION "superserial")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(NOT DEFINED PHARE_CPPDICT_VERION)
SET(PHARE_CPPDICT_VERION "superserial")
if(NOT DEFINED PHARE_CPPDICT_VERSION)
SET(PHARE_CPPDICT_VERSION "superserial")

Comment on lines +12 to +14
if(NOT DEFINED PHARE_PYBIND11_VERSION)
SET(PHARE_PYBIND11_VERSION "master")
endif()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Version override mechanism is ineffective.

While you've added a check for PHARE_PYBIND11_VERSION, it's not being used. The PYBIND11_VERSION is hardcoded to "master" a few lines below, making this conditional check ineffective.

Apply this diff to fix the version management:

  if(NOT DEFINED PHARE_PYBIND11_VERSION)
    SET(PHARE_PYBIND11_VERSION "master")
  endif()

  message("downloading subproject pybind11")
  set(PYBIND11_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/subprojects/pybind11)
- set(PYBIND11_VERSION master)
+ set(PYBIND11_VERSION ${PHARE_PYBIND11_VERSION})

Committable suggestion was skipped due to low confidence.


💡 Codebase verification

Version compatibility issue detected

The default version "master" in pybind.cmake is problematic as it:

  1. Doesn't guarantee compatibility with the minimum required version 2.5.0
  2. Conflicts with the release version v2.13.6 specified in release.cmake
  3. Could lead to inconsistent builds due to using a moving target

Recommendations:

  • Replace "master" with "v2.13.6" in the default version setting to maintain consistency with release.cmake
  • This version is well above the minimum requirement of 2.5.0 and provides a stable reference
🔗 Analysis chain

Verify version compatibility.

Please ensure that the default version is compatible with the minimum version requirement (PYBIND_MIN_VERSION "2.5.0").

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the version specified in release.cmake exists
# and verify its compatibility with PYBIND_MIN_VERSION

# Test: Look for version specifications in release.cmake
echo "Checking version in release.cmake:"
rg "PHARE_PYBIND11_VERSION" res/cmake/release.cmake

Length of output: 168


Script:

#!/bin/bash
# Let's check for PYBIND_MIN_VERSION in the codebase
echo "Searching for PYBIND_MIN_VERSION:"
rg "PYBIND_MIN_VERSION"

# Also check the pybind.cmake file content for context
echo -e "\nChecking pybind.cmake content:"
cat res/cmake/dep/pybind.cmake

Length of output: 1216

Comment on lines +6 to +8
if(NOT DEFINED PHARE_HIGHFIVE_VERSION)
SET(PHARE_HIGHFIVE_VERSION "master")
endif()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using a specific version as default instead of "master".

Using "master" as the default version could lead to non-reproducible builds. Consider using a specific stable version (e.g., "v2.10.0") as the default to ensure build consistency, while still allowing overrides when needed.

  if(NOT DEFINED PHARE_HIGHFIVE_VERSION)
-    SET(PHARE_HIGHFIVE_VERSION "master")
+    SET(PHARE_HIGHFIVE_VERSION "v2.10.0")
  endif()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(NOT DEFINED PHARE_HIGHFIVE_VERSION)
SET(PHARE_HIGHFIVE_VERSION "master")
endif()
if(NOT DEFINED PHARE_HIGHFIVE_VERSION)
SET(PHARE_HIGHFIVE_VERSION "v2.10.0")
endif()

Comment on lines +57 to +74
void inline dump_phare_dict(PHAREDict const& dict, std::string const& filename)
{
using Serializer
= cppdict::DictSerializer<bool, int, std::vector<int>, double, std::vector<double>,
std::size_t, std::optional<std::size_t>, std::string,
InitFunction<1>, InitFunction<2>, InitFunction<3>>;

Serializer{filename}(dict);
}

auto inline load_phare_dict(std::string const& filename)
{
using Deserializer
= cppdict::DictDeSerializer<bool, int, std::vector<int>, double, std::vector<double>,
std::size_t, std::optional<std::size_t>, std::string,
InitFunction<1>, InitFunction<2>, InitFunction<3>>;
return Deserializer{filename}();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add documentation and improve error handling for serialization functions.

Several improvements needed:

  1. Add documentation explaining the purpose, parameters, and potential exceptions
  2. Add error handling for file operations
  3. Make return type explicit for better readability

Here's the suggested improvement:

+/**
+ * @brief Serializes a PHAREDict to a file
+ * @param dict The dictionary to serialize
+ * @param filename The target file path
+ * @throw std::runtime_error if file operations fail
+ */
 void inline dump_phare_dict(PHAREDict const& dict, std::string const& filename)
 {
     using Serializer
         = cppdict::DictSerializer<bool, int, std::vector<int>, double, std::vector<double>,
                                   std::size_t, std::optional<std::size_t>, std::string,
                                   InitFunction<1>, InitFunction<2>, InitFunction<3>>;
-    Serializer{filename}(dict);
+    try {
+        Serializer{filename}(dict);
+    } catch (const std::exception& e) {
+        throw std::runtime_error("Failed to serialize PHAREDict: " + std::string(e.what()));
+    }
 }

+/**
+ * @brief Deserializes a PHAREDict from a file
+ * @param filename The source file path
+ * @return PHAREDict The deserialized dictionary
+ * @throw std::runtime_error if file operations fail
+ */
-auto inline load_phare_dict(std::string const& filename)
+PHAREDict inline load_phare_dict(std::string const& filename)
 {
     using Deserializer
         = cppdict::DictDeSerializer<bool, int, std::vector<int>, double, std::vector<double>,
                                     std::size_t, std::optional<std::size_t>, std::string,
                                     InitFunction<1>, InitFunction<2>, InitFunction<3>>;
-    return Deserializer{filename}();
+    try {
+        return Deserializer{filename}();
+    } catch (const std::exception& e) {
+        throw std::runtime_error("Failed to deserialize PHAREDict: " + std::string(e.what()));
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void inline dump_phare_dict(PHAREDict const& dict, std::string const& filename)
{
using Serializer
= cppdict::DictSerializer<bool, int, std::vector<int>, double, std::vector<double>,
std::size_t, std::optional<std::size_t>, std::string,
InitFunction<1>, InitFunction<2>, InitFunction<3>>;
Serializer{filename}(dict);
}
auto inline load_phare_dict(std::string const& filename)
{
using Deserializer
= cppdict::DictDeSerializer<bool, int, std::vector<int>, double, std::vector<double>,
std::size_t, std::optional<std::size_t>, std::string,
InitFunction<1>, InitFunction<2>, InitFunction<3>>;
return Deserializer{filename}();
}
/**
* @brief Serializes a PHAREDict to a file
* @param dict The dictionary to serialize
* @param filename The target file path
* @throw std::runtime_error if file operations fail
*/
void inline dump_phare_dict(PHAREDict const& dict, std::string const& filename)
{
using Serializer
= cppdict::DictSerializer<bool, int, std::vector<int>, double, std::vector<double>,
std::size_t, std::optional<std::size_t>, std::string,
InitFunction<1>, InitFunction<2>, InitFunction<3>>;
try {
Serializer{filename}(dict);
} catch (const std::exception& e) {
throw std::runtime_error("Failed to serialize PHAREDict: " + std::string(e.what()));
}
}
/**
* @brief Deserializes a PHAREDict from a file
* @param filename The source file path
* @return PHAREDict The deserialized dictionary
* @throw std::runtime_error if file operations fail
*/
PHAREDict inline load_phare_dict(std::string const& filename)
{
using Deserializer
= cppdict::DictDeSerializer<bool, int, std::vector<int>, double, std::vector<double>,
std::size_t, std::optional<std::size_t>, std::string,
InitFunction<1>, InitFunction<2>, InitFunction<3>>;
try {
return Deserializer{filename}();
} catch (const std::exception& e) {
throw std::runtime_error("Failed to deserialize PHAREDict: " + std::string(e.what()));
}
}

Comment on lines +100 to +111
int r = 0;

r += dict["ions"]["nbrPopulations"].to<std::size_t>() != 2;

r += dict["ions"]["pop0"]["particle_initializer"]["nbrPartPerCell"].to<int>() != 100;
r += dict["ions"]["pop1"]["particle_initializer"]["nbrPartPerCell"].to<int>() != 100;

r += dict["electromag"]["magnetic"]["initializer"]["x_component"].isValue(); // NOT SERIALIZABLE

r += dict["electrons"]["pressure_closure"]["Te"].to<double>() != 0.12;

return r;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance test failure reporting and cleanup.

The current error accumulation pattern makes it difficult to identify which specific checks failed. Consider these improvements:

int main(int argc, char** argv) {
    std::string const filename = "pharedict.dat";
    PHARE::initializer::dump_phare_dict(createDict(), filename);
    
    auto const dict = PHARE::initializer::PHAREDictHandler::load(filename);
    int failures = 0;
    
    auto check = [&failures](bool condition, const char* message) {
        if (!condition) {
            std::cerr << "Test failed: " << message << std::endl;
            failures++;
        }
    };
    
    check(dict["ions"]["nbrPopulations"].to<std::size_t>() == 2, 
          "Incorrect number of populations");
    // ... other checks ...
    
    std::filesystem::remove(filename);  // Cleanup
    return failures;
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (4)
src/initializer/data_provider.hpp (2)

57-74: Reconsider using inline for I/O operations.

The inline keyword is typically used for small, frequently called functions. For I/O operations that are relatively expensive and less frequently called, using inline might not be beneficial and could potentially increase code size without performance benefits.


95-99: Improve clarity of the load method implementation.

The current implementation combines reset and assignment in a way that's not immediately clear. Consider splitting these operations for better readability:

 static auto& load(std::string const& filename)
 {
     INSTANCE().phareDict = std::make_unique<PHAREDict>();       // reset
-    return (*INSTANCE().phareDict = load_phare_dict(filename)); // ?
+    *INSTANCE().phareDict = load_phare_dict(filename);
+    return *INSTANCE().phareDict;
 }

Also, the comment "// ?" suggests uncertainty about the implementation. Please either remove it or replace it with a meaningful comment explaining the implementation choice.

tests/initializer/phare_dict.cpp (2)

96-96: Remove commented-out code.

Dead code should be removed rather than commented out. If this alternative loading method is important, consider adding it as a separate test case.


107-107: Enhance the "NOT SERIALIZABLE" comment.

The current comment lacks context about why the component is not serializable and what developers should do about it.

Consider expanding the comment:

// InitFunction types are not serializable by design - they represent runtime function objects
// This check verifies that serialization correctly handles this limitation
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2f32ac1 and 6325940.

📒 Files selected for processing (7)
  • res/cmake/dep/cppdict.cmake (1 hunks)
  • res/cmake/dep/highfive.cmake (1 hunks)
  • res/cmake/dep/pybind.cmake (1 hunks)
  • res/cmake/dep/samrai.cmake (1 hunks)
  • res/cmake/release.cmake (1 hunks)
  • src/initializer/data_provider.hpp (3 hunks)
  • tests/initializer/phare_dict.cpp (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • res/cmake/dep/cppdict.cmake
  • res/cmake/dep/highfive.cmake
  • res/cmake/dep/pybind.cmake
  • res/cmake/dep/samrai.cmake
  • res/cmake/release.cmake
🧰 Additional context used
📓 Path-based instructions (1)
src/initializer/data_provider.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

🔇 Additional comments (4)
src/initializer/data_provider.hpp (2)

14-15: LGTM: Include statement is properly placed.

The serializer include follows proper include ordering and is necessary for the new functionality.


57-74: Previous review comments about documentation and error handling are still applicable.

tests/initializer/phare_dict.cpp (2)

1-11: LGTM! Headers and declarations are well organized.

The includes are appropriate for the test's requirements and the type alias improves code readability.


12-88: Consider extracting magic numbers as named constants.

The function uses magic numbers that could be better expressed as named constants:

  • 100 for nbrPartPerCell
  • 0.12 for electron temperature Te

This would improve maintainability and make the test's intent clearer.

Example:

constexpr int PARTICLES_PER_CELL = 100;
constexpr double ELECTRON_TEMPERATURE = 0.12;

Comment on lines +92 to +112
int main(int argc, char** argv)
{
std::string const filename = "pharedict.dat";
PHARE::initializer::dump_phare_dict(createDict(), filename);
// auto const dict = PHARE::initializer::load_phare_dict(filename);

auto const dict = PHARE::initializer::PHAREDictHandler::load(filename);

int r = 0;

r += dict["ions"]["nbrPopulations"].to<std::size_t>() != 2;

r += dict["ions"]["pop0"]["particle_initializer"]["nbrPartPerCell"].to<int>() != 100;
r += dict["ions"]["pop1"]["particle_initializer"]["nbrPartPerCell"].to<int>() != 100;

r += dict["electromag"]["magnetic"]["initializer"]["x_component"].isValue(); // NOT SERIALIZABLE

r += dict["electrons"]["pressure_closure"]["Te"].to<double>() != 0.12;

return r;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance test robustness and cleanup.

The test function could be improved in several ways:

  1. Add file cleanup using RAII or try-finally
  2. Improve error reporting
  3. Add test documentation

Consider this improved structure:

int main(int argc, char** argv)
{
    const std::string filename = "pharedict.dat";
    
    // Use RAII for file cleanup
    struct FileCleanup {
        std::string filename;
        ~FileCleanup() { std::filesystem::remove(filename); }
    } cleanup{filename};
    
    PHARE::initializer::dump_phare_dict(createDict(), filename);
    auto const dict = PHARE::initializer::PHAREDictHandler::load(filename);
    
    struct TestResult {
        int failures = 0;
        void check(bool condition, const char* message) {
            if (!condition) {
                std::cerr << "Test failed: " << message << '\n';
                ++failures;
            }
        }
    } result;
    
    result.check(dict["ions"]["nbrPopulations"].to<std::size_t>() == 2,
                "Expected 2 ion populations");
    result.check(dict["ions"]["pop0"]["particle_initializer"]["nbrPartPerCell"].to<int>() == 100,
                "Expected 100 particles per cell for pop0");
    // ... other checks ...
    
    return result.failures;
}

@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Oct 29, 2024
Copy link
Member

@nicolasaunai nicolasaunai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this is not finished since I see cppdict points to your repo and the phare dict test is not plugged to cmake/gtest and only tests some of the dict values.

{
std::string const filename = "pharedict.dat";
PHARE::initializer::dump_phare_dict(createDict(), filename);
// auto const dict = PHARE::initializer::load_phare_dict(filename);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


r += dict["electrons"]["pressure_closure"]["Te"].to<double>() != 0.12;

return r;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is a non-zero return value visible as an error in our tests?
I don't see this test added in the cmake tests, should probably be included (as a gtest)?

r += dict["ions"]["pop0"]["particle_initializer"]["nbrPartPerCell"].to<int>() != 100;
r += dict["ions"]["pop1"]["particle_initializer"]["nbrPartPerCell"].to<int>() != 100;

r += dict["electromag"]["magnetic"]["initializer"]["x_component"].isValue(); // NOT SERIALIZABLE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the comment mean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

functions are not serializable, so we don't expect a value here


PHARE::initializer::PHAREDict createDict()
{
PHARE::initializer::PHAREDict dict;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to include data_provider.hpp I think


set(CPPDICT_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/subprojects/cppdict)
# phare_github_get_or_update(cppdict ${CPPDICT_SRCDIR} LaboratoryOfPlasmaPhysics/cppdict ${PHARE_CPPDICT_VERION})
phare_github_get_or_update(cppdict ${CPPDICT_SRCDIR} PhilipDeegan/cppdict ${PHARE_CPPDICT_VERION})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not yet merged to master I guess

@PhilipDeegan
Copy link
Member Author

I suspect this is not finished since I see cppdict points to your repo and the phare dict test is not plugged to cmake/gtest and only tests some of the dict values.

yes this branch is currently hijacked to test serialization in a cppdict fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants