How to avoid dynamic memory allocation, and templates for matricez using Eigen library in C++

Hello dear all

Look i am using the library Eigen, for Matrix and vector calculations.

when, i tried to generate a matrix using advance initialization i want to avoid the dynamic allocation, therefore what i just did is the, following.

Matrix<int, 20, 20, RowMajor> m_MDoF;

Declare the typename "int" matrix size, and the RowMajor. At this point everything looks quite good. However, when i tried to generate the matrix in a class does not seems ok.

Look, my matrix size is composed by a variable which is passed though the constructor, then, when i run the code anything works. What tried, was the use the maximum size of rows and maximum size of columns. like this

Matrix<int, Dynamic, Dynamic, RowMajor, 20, 20> m_MDoF;

and now everything works, BUT MUST NOTICE THAT I WAS FORCED TO PLACE A 20, 20 as a maximum in rows and columns.

Hence, i decided to replace the "20" by a variable that i passed through the constructor, and the code does not work.

One of my ideas that actually i already tested, was using class templates

1
2
3
template<int numberRows, int numberCols>
.....
Matrix<int, Dynamic, Dynamic, RowMajor, numberRows, numberCols> m_MDoF;




everything works quite nice.

However, i was wondering if there is a possibility to avoid the dynamic memory allocation and templates.

This my code.

the main cpp file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <bits/stdc++.h>
#include <Eigen/LU>
#include "MDoF.h"

using std::cout;
using std::endl;
using Eigen::Matrix;
using Eigen::RowMajor;
using Eigen::ColMajor;
using Eigen::Dynamic;

int main(int argc, char const *argv[])
{
	#ifndef ONLINE_JUDGE
		//freopen("input.txt", "r", stdin); // file to make input data.
		freopen("output.txt", "w", stdout); // file to store the output data.
	#endif

	/*--------------- MAIN VARIABLES ---------------*/

	const unsigned int nNodes = 5; // number of nodes
	const unsigned int nDofNode = 2; // number of DoF per node
	const unsigned int nElements = 7; // number of elements
	const unsigned int nNodesElement = 2; // number of nodes per element

	/* --------------- INSTANTIATION --------------- */
	/* ---------- VARIABLES INITIALIZATION ---------- */
	
	MDoF mDoF(nNodes, nDofNode, nElements, nNodesElement);

	return 0;
}



This is my class using eigen library

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#pragma once
#include <bits/stdc++.h>
#include <Eigen/LU>

using std::cout;
using std::endl;
using Eigen::Matrix;
using Eigen::RowMajor;
using Eigen::ColMajor;
using Eigen::Dynamic;

class MDoF
{
private:
	const unsigned int m_nNodes; // (nRows)
	const unsigned int m_nDofNode; // (nCols)
	const unsigned int m_nElements; // (nRowsTwo)
	const unsigned int m_nNodesElement; // (nColsTwo)

protected:
	Matrix<int, Dynamic, Dynamic, RowMajor, 20, 20> m_MDoF;

public:
	MDoF(const unsigned int nNodes, const unsigned int nDofNode, const unsigned int nElements, const unsigned int nNodesElement);
	~MDoF();
};

MDoF::MDoF(const unsigned int nNodes, const unsigned int nDofNode, const unsigned int nElements, const unsigned int nNodesElement)
	: m_nNodes(nNodes),
	  m_nDofNode(nDofNode),
	  m_nElements(nElements),
	  m_nNodesElement(nNodesElement)
{
	m_MDoF.resize(m_nNodes, m_nDofNode);
	m_MDoF.setZero();
	cout << m_MDoF << endl;
}

MDoF::~MDoF()
{
}


If you replace the 20 by m_nNodes and m_nDofNode the code does not work.
Last edited on
What is your purpose for avoiding templates?
What is your purpose for avoiding dynamic allocation?

It is important to know why you want to avoid these things, so we can suggest approaches that address your concerns.
mbozzi Thank you very much for your answer.

Look, in the case of templates is because the project is not only mine, and the other people involved (bosses) do not wanna get involved with templates, according to them if templates are not well applied they can generate huge problems and errors that are quite hard to figure them out. At this point, and in my opinion, using templates is not a big issue, because only two simple variables are called, but for the others templates are issues because the class will grow and some many other important functions are going to be implemented, and as a result many more variables and some other libraries that actually call another predefined templates similar to those for Eigen.

For Dynamic allocation, is because using the dynamic allocation the program slows down, we are working with matrices quite big (100000 X 100000, even more) elements. In the example provided i only mentioned 20 X 20 but that's one tiny matrix, later one ill face quite big matrix.

Please correct me if i am wrong, and also can you give me some ideas or mainly your opinion,
> using the dynamic allocation the program slows down

Quite unlikely to have any perceptible slow down if the matrices are large. Measure it.
dynamic memory slows you down when you do slow things with it:
- 2-d allocation, eg outer = new inner*[big]; for (...) outer[i] = new whatever[bigcols];
- reallocation/copies: (decided to change size to append a column for RREF or whatnot, or append an identity for inverse?)
- unnecessary creation and destruction of memory in tight loops. Keep the memory around, allocate it OUTSIDE the function(s) and pass it in, reuse it, dispose of it later. Or have a memory manager that reuses objects.
- you need something smart for 100000 X 100000. if that is only a single double, that is still 8 * 10^10 bytes per matrix (75GB), and I assume you want at least 2 active at a time. You are going to need to break it into chunks and process it in parallel for those sizes, and if sparse, handle it smarter that way.

bottom line echos what was said though... if you manage your memory, dynamic memory is not going to be your bottleneck whether you do it via vectors/valarrays or raw pointers. Its like anything else, if you misuse it, it can be slow, but that is programmer error, really.

Templates are useful if you need them. Like much of OOP, they are frequently misused and that makes an unholy mess. I can bust up my house with a sledgehammer or an axe too, but that isnt the tool's fault.
Last edited on
Look, in the case of templates is because the project is not only mine, and the other people involved (bosses) .....


Crap.

You have bosses that let you do Online Judge?

#ifndef ONLINE_JUDGE

And let you write code like:

#include <bits/stdc++.h>

https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h

If you really had a boss , I would have expected professional code.

For Dynamic allocation, is because using the dynamic allocation the program slows down, we are working with matrices quite big (100000 X 100000, even more) elements.


More crap. How do you expect to do this with out dynamic memory, do you have a 75GB stack?
Last edited on
Jonnin, thank you very much for your answer, I've been reading info about, the people who claimed that templates and memory allocation are 'bad' and is better to avoid them, also I noticed that learning C++ in the university is best way to learn C++. In many cases this forums and some other info in the internet are more relevant updated and way more explained.
Yes according to the matrices I'll break them small chunks.

Thank you very much.
that said,
dynamic memory is 'best avoided'. The c++ containers (like vector) do it for you cleanly, but doing a bunch of it yourself is error prone. Your gigantic problem may be a good example of a time when you really do need to do that for yourself, building a simple memory manager, but more generally ... avoid it. Its there if you do need it. This does not mean dynamic memory is 'bad' ... programming is not binary (hahah) in that sense. Even some of the things consistently labeled "bad" are sometimes useful, like the well known use of a goto to get out of nested loops.

you will get a feel for best practices and when to break them as you gain experience. For now, follow best practices until you hit a wall and then ask around to see if you have found a place to color outside the lines.

If you are lurking somewhere that consistently says major features of C++ are bad, get away from there. It is probably people who prefer another language .. about 1/2 the java books out there start out immediately telling you why c or c++ is not any good in their intro.
Last edited on
Jonnin, i never got such an nice answer telling the truth, Thank you very much.

you know probably most of the big mistakes made by beginners like me are: just watching tutorials and more tutorials and never getting involved with real projects, therefore we never "hit" the wall with a real situation. i am saying that because that was my case. Now i am in a project on which actually i am seeing things that never saw before, i am using things that many people claim they are "bad", and those "bad" things well implemented give you nice results.

You are right most of the people and even nice articles mention "bad" things about the language and the different libraries. But the problem is that we never fell the experience, and we just follow what others just said, just because they have more experience than us.

i am already using the library Eigen that works with the dynamic memory and the code seems quite nice, clean and also the results along with the time, are good as well.

Later on ill have to face how to break the matrices into small chunks, but everything has be solved step by step.

Thank you very much
Last edited on
Topic archived. No new replies allowed.