Skip to content

rootext: Reimplement MatOp in pure C++#53

Open
heijligen wants to merge 2 commits intohdtv-tool:masterfrom
heijligen:matop
Open

rootext: Reimplement MatOp in pure C++#53
heijligen wants to merge 2 commits intohdtv-tool:masterfrom
heijligen:matop

Conversation

@heijligen
Copy link
Contributor

This patch is a step in a upcoming series to reduce the C/C++ code in HDTV and make it either be precompiled (mfile, with no ROOT dependency) or load via the ROOT CLING interpreter.

Commit Message:

MatOp.cc implements projection and transposing of mfile based matrices with the help of functions derived from the matop package.

Reimplement those two functions directly in C++ to reduce code size and complexity. Furthermore, this helps to prepare the rootext code to be loaded via the ROOT CLING interpreter.

The new implementation was A/B tested against the original implementation with the matrices in src/hdtv/rootext/mfile-root/mfile/spec-samples: 1k.hf4, 1k.hf8, 1k.lf4, 1k.lf8, 1k.txt.

hdtv> matrix get asym src/hdtv/rootext/mfile-root/mfile/spec-samples/1k.*

The generated files were the same.
The transpose of 1k.vaxf and 1k.vaxg failed both, before and after this patch.

Testing

The testsuite does not cover loading and generating the projections and transformations of mfile matrices. A/B testing was done manually with the limited fies in the mfile-samples directory.

Copyright

The original matop/matop_*** C code was copyrighted under the BSD-3-Clause license. The HDTV code is under GPL-2.0-or-later. I'm unsure what the correct way here is. Part of the new core is inherited from the BSD code, some is new, some has a strong influence.


@h-mayr: This patch touches the behavior of HDTV, even if it should not change anything.

@codecov
Copy link

codecov bot commented Jan 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.83%. Comparing base (4374fa9) to head (0546bef).
⚠️ Report is 33 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #53      +/-   ##
==========================================
- Coverage   63.07%   62.83%   -0.24%     
==========================================
  Files          70       69       -1     
  Lines       10066     9870     -196     
==========================================
- Hits         6349     6202     -147     
+ Misses       3717     3668      -49     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.


// Write
for (int32_t c = 0; c < cc; c++) {
if (mput_(dst_matrix, &buffer[c], level, column + c, line, ll) != ll) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same as above, this is reading from overlapping chunks of buffer.

@heijligen
Copy link
Contributor Author

It seems the data from mfile-samples I used were quite limited. But I don't have better files for testing

@heijligen
Copy link
Contributor Author

heijligen commented Jan 16, 2026

I got a bigger matrix from @h-mayr, tried it and the matrix transpose failed. Digging into it, I found that the new code is in theory correct, BUT the default matrix format is MAT_LC, which is line compressed. It does not support writes to random positions. So it produces a wrong transpose. It also does not fail when trying.

Using MAT_TXT I got a good loking transpose, but with a file ~50 times as large.

I'll look deeper into it :(

left: original matrix, center: old code, right: new code but with MAT_TXT.
20260116_22h21m41s_grim

@heijligen heijligen force-pushed the matop branch 2 times, most recently from fee2059 to 0546bef Compare January 18, 2026 14:05
@heijligen
Copy link
Contributor Author

-> Fixed previous issues

I've reimplemented TransposeGeneric as a simplified version of the original code. I added a comment why it is implemented this way.

I've tested the code with the matrix from the last comment. Now the md5 hashes of the generated files matches those of the original code. Also when reducing MAX_BUFFER_ELEMENTS to different sizes.

@op3
Copy link
Collaborator

op3 commented Jan 18, 2026

I think it would be best to add some unit or component tests to verify the behavior of MatOp

@heijligen
Copy link
Contributor Author

I could add A/B testing if the code produces the same results as before with known matrices. Aka, adding the test I've done manually to pytest. I found no easy way to generate test files within pytest.
This would be possible when loading libmfile directly into ROOT, which is on my roadmap for the near future.

How should I continue here?

@heijligen
Copy link
Contributor Author

heijligen commented Feb 7, 2026

I get more and more confused about the existing code

I've added a test code and the original code shoes some unexpected behavior
In the original code a matrix with 73 lines and 127 columns is transposed into a 73 times 73 matrix. A matrix with 127 columns and 73 lines failed to be transposed.

(left: the input (73x172), middle: the result with the old code, right: the new code / my expectation / caution: the axis scaling is a bit confusing here)
20260207_11h58m21s_grim

@janmayer @nfbraun: Could you explain why the code behaves this way?

@heijligen
Copy link
Contributor Author

Ok, I digged deeper. The old transpose code produces a matrix with the right size, but the matrix is not fully transposed. In the matrix from above, lines 74-126 are 0. So is this intended behavior in the old code or a bug?

a.mtx is a copy of complex.mtx, a.tmtx is generated from HDTV with matrix get asym a.mtx

~> ./mtx_info ../../a.mtx
  Matrix: ../../a.mtx
    Filetype: 8
    Levels:   1
    Lines:    73
    Columns:  127
    Version:  2
    Status:   0
    Name:     ../../a.mtx
    Comment:  (null)

~> ./mtx_info ../../a.tmtx
  Matrix: ../../a.tmtx
    Filetype: 8
    Levels:   1
    Lines:    127
    Columns:  73
    Version:  2
    Status:   0
    Name:     ../../a.tmtx
    Comment:  (null)

Currently there is no interface that allows yout to generate mfiles on
the fly with Python. Therefore all testing data must be checked-in as
blobs. To limit the file sizes of these blobs, only two small matrices
and their transposes are checked in.

These matrices were generated using `create_mtx.c`. This code can also
generate larger matrices to test possible edge cases in the
MatOp.Transpose implementation.
MatOp.cc implements projection and transposing of mfile based matrices
with the help of functions derived from the matop package.

Reimplement those two functions directly in C++ to reduce code size and
complexity. Furthermore, this helps to prepare the rootext code to be
loaded via the ROOT CLING interpreter.
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