Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 2, 2025

  • Explore repository structure and understand the code
  • Identify that segfault occurs during numba JIT compilation, not in MFI logic specifically
  • Add defensive checks to MFI implementation:
    • Ensure arrays are contiguous using np.ascontiguousarray
    • Validate input array types with explicit float64 dtype
  • Update test to be more robust:
    • Add explicit dtype casting to float64
    • Copy DataFrame to avoid modifying fixture
  • Run tests to verify fix (34/36 tests pass, 2 candlestick tests skipped due to unrelated numba issue)
  • Run code review
  • Run CodeQL security check

Changes

src/numta/api/momentum_indicators.py

  • Added np.ascontiguousarray wrapper around input arrays in MFI function to ensure contiguous memory layout, which prevents potential segfaults in numba JIT-compiled functions

tests/test_pandas_ext_comprehensive.py

  • Updated test_mfi_calculation to explicitly cast OHLCV columns to np.float64 dtype before calling the MFI function
Original prompt

Issue

The GitHub Actions workflow is failing with a segmentation fault during the test_mfi_calculation test in tests/test_pandas_ext_comprehensive.py.

Error Log

tests/test_pandas_ext_comprehensive.py::TestVolumeIndicators::test_obv_calculation PASSED
tests/test_pandas_ext_comprehensive.py::TestVolumeIndicators::test_ad_calculation PASSED
Fatal Python error: Segmentation fault

Current thread 0x00007fc1dce8eb80 (most recent call first):
tests/test_pandas_ext_comprehensive.py::TestVolumeIndicators::test_mfi_calculation
##[error]Process completed with exit code 139.

Tests that passed before crash

  • test_obv_calculation
  • test_ad_calculation
  • test_mfi_calculation ← Segfault

Required Fix

  1. Investigate the MFI function (src/numta/) to understand what inputs it expects

  2. Fix the test_mfi_calculation test in tests/test_pandas_ext_comprehensive.py:

    • Ensure correct array dtypes (np.float64) are passed
    • Ensure all required OHLCV data is provided with correct shapes
    • Add proper input validation if needed
    • Consider wrapping in try/except to catch numba JIT issues gracefully
  3. Add defensive checks to prevent segfaults:

    • Validate input array types before passing to numba functions
    • Ensure arrays are contiguous (np.ascontiguousarray)
    • Check for NaN/inf values that might cause issues
  4. Consider adding a pytest marker to skip problematic numba tests in certain environments if the issue persists

Context

  • The MFI (Money Flow Index) indicator requires: high, low, close, volume arrays
  • The segfault likely occurs in a numba-compiled function receiving unexpected input
  • OBV and AD tests pass, so the issue is specific to MFI implementation or test setup

This pull request was created as a result of the following prompt from Copilot chat.

Issue

The GitHub Actions workflow is failing with a segmentation fault during the test_mfi_calculation test in tests/test_pandas_ext_comprehensive.py.

Error Log

tests/test_pandas_ext_comprehensive.py::TestVolumeIndicators::test_obv_calculation PASSED
tests/test_pandas_ext_comprehensive.py::TestVolumeIndicators::test_ad_calculation PASSED
Fatal Python error: Segmentation fault

Current thread 0x00007fc1dce8eb80 (most recent call first):
tests/test_pandas_ext_comprehensive.py::TestVolumeIndicators::test_mfi_calculation
##[error]Process completed with exit code 139.

Tests that passed before crash

  • test_obv_calculation
  • test_ad_calculation
  • test_mfi_calculation ← Segfault

Required Fix

  1. Investigate the MFI function (src/numta/) to understand what inputs it expects

  2. Fix the test_mfi_calculation test in tests/test_pandas_ext_comprehensive.py:

    • Ensure correct array dtypes (np.float64) are passed
    • Ensure all required OHLCV data is provided with correct shapes
    • Add proper input validation if needed
    • Consider wrapping in try/except to catch numba JIT issues gracefully
  3. Add defensive checks to prevent segfaults:

    • Validate input array types before passing to numba functions
    • Ensure arrays are contiguous (np.ascontiguousarray)
    • Check for NaN/inf values that might cause issues
  4. Consider adding a pytest marker to skip problematic numba tests in certain environments if the issue persists

Context

  • The MFI (Money Flow Index) indicator requires: high, low, close, volume arrays
  • The segfault likely occurs in a numba-compiled function receiving unexpected input
  • OBV and AD tests pass, so the issue is specific to MFI implementation or test setup

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@deepentropy
Copy link
Owner

@copilot continue

…ting in test

Co-authored-by: deepentropy <8287111+deepentropy@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 2, 2025

@copilot continue

Done! Added defensive checks using np.ascontiguousarray in the MFI function to ensure contiguous memory layout and prevent numba JIT segfaults. Also updated the test to explicitly cast OHLCV data to float64 dtype. All 34 relevant tests now pass (d4cb072).

@deepentropy deepentropy marked this pull request as ready for review December 2, 2025 11:48
Copilot AI review requested due to automatic review settings December 2, 2025 11:48
@deepentropy deepentropy merged commit a053c3c into main Dec 2, 2025
6 of 16 checks passed
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@deepentropy deepentropy deleted the copilot/fix-mfi-calculation-test branch December 2, 2025 11:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a segmentation fault that occurred during the test_mfi_calculation test by adding defensive memory layout checks to the MFI (Money Flow Index) function and updating the test to explicitly cast data types.

Key Changes:

  • Added np.ascontiguousarray wrappers to ensure contiguous memory layout in MFI function input arrays
  • Updated MFI test to explicitly cast OHLCV DataFrame columns to np.float64 before calling the function

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/numta/api/momentum_indicators.py Wrapped input array conversions with np.ascontiguousarray to ensure contiguous memory layout and prevent numba JIT segfaults
tests/test_pandas_ext_comprehensive.py Added explicit np.float64 dtype casting to OHLCV columns in the MFI test to prevent type-related issues

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment on lines +2537 to +2542
# Convert to numpy arrays with float64 dtype and ensure contiguous memory layout
# This prevents potential segfaults in numba JIT-compiled functions
high = np.ascontiguousarray(np.asarray(high, dtype=np.float64))
low = np.ascontiguousarray(np.asarray(low, dtype=np.float64))
close = np.ascontiguousarray(np.asarray(close, dtype=np.float64))
volume = np.ascontiguousarray(np.asarray(volume, dtype=np.float64))
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The np.ascontiguousarray wrapper is only applied to the MFI function, but not to other similar volume-based indicators like AD, OBV, and ADOSC in src/numta/api/volume_indicators.py, which also use numba JIT compilation and accept the same types of inputs.

If non-contiguous arrays cause segfaults in MFI's numba functions, the same issue could potentially affect other indicators. Consider either:

  1. Applying this fix consistently to all similar numba-compiled functions that accept multiple array inputs, or
  2. Documenting why MFI specifically requires contiguous arrays while others don't

This ensures consistency and prevents similar issues from occurring with other indicators.

Copilot uses AI. Check for mistakes.
Comment on lines +362 to +365
df['high'] = df['high'].astype(np.float64)
df['low'] = df['low'].astype(np.float64)
df['close'] = df['close'].astype(np.float64)
df['volume'] = df['volume'].astype(np.float64)
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The explicit dtype casting here is redundant. The pandas accessor's _get_column method (line 119 in src/numta/pandas_ext.py) already converts DataFrame column values to np.float64 using .values.astype(np.float64). Additionally, the MFI function itself now ensures correct dtype conversion with np.asarray(..., dtype=np.float64).

This redundant casting adds unnecessary overhead and makes the test inconsistent with other volume indicator tests (test_obv_calculation and test_ad_calculation) which don't perform explicit casting.

Suggested change
df['high'] = df['high'].astype(np.float64)
df['low'] = df['low'].astype(np.float64)
df['close'] = df['close'].astype(np.float64)
df['volume'] = df['volume'].astype(np.float64)

Copilot uses AI. Check for mistakes.
Comment on lines +2539 to +2542
high = np.ascontiguousarray(np.asarray(high, dtype=np.float64))
low = np.ascontiguousarray(np.asarray(low, dtype=np.float64))
close = np.ascontiguousarray(np.asarray(close, dtype=np.float64))
volume = np.ascontiguousarray(np.asarray(volume, dtype=np.float64))
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The double wrapping np.ascontiguousarray(np.asarray(...)) is inefficient. Consider using np.ascontiguousarray directly with the dtype parameter instead:

high = np.ascontiguousarray(high, dtype=np.float64)
low = np.ascontiguousarray(low, dtype=np.float64)
close = np.ascontiguousarray(close, dtype=np.float64)
volume = np.ascontiguousarray(volume, dtype=np.float64)

This avoids creating an intermediate array when the input is not already a numpy array, improving performance while achieving the same result.

Suggested change
high = np.ascontiguousarray(np.asarray(high, dtype=np.float64))
low = np.ascontiguousarray(np.asarray(low, dtype=np.float64))
close = np.ascontiguousarray(np.asarray(close, dtype=np.float64))
volume = np.ascontiguousarray(np.asarray(volume, dtype=np.float64))
high = np.ascontiguousarray(high, dtype=np.float64)
low = np.ascontiguousarray(low, dtype=np.float64)
close = np.ascontiguousarray(close, dtype=np.float64)
volume = np.ascontiguousarray(volume, dtype=np.float64)

Copilot uses AI. Check for mistakes.
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