Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 07a9105a authored by BRAMAS Berenger's avatar BRAMAS Berenger
Browse files

add cuda help classes (mem object and timer)

parent 73e71b6e
No related branches found
No related tags found
No related merge requests found
#ifndef FCUDADATA_HPP
#define FCUDADATA_HPP
#include "FCudaGlobal.hpp"
template <class ObjectClass>
class FCudaData{
protected:
ObjectClass* cudaPtr;
FSize nbElements;
void allocAndCopy(const ObjectClass* inCpuPtr, const FSize inNbElements){
FCudaCheck( cudaMalloc(&cudaPtr,inNbElements*sizeof(ObjectClass)) );
FCudaCheck( cudaMemcpy( cudaPtr, inCpuPtr, inNbElements*sizeof(ObjectClass),
cudaMemcpyHostToDevice ) );
}
void dealloc(){
FCudaCheck(cudaFree(cudaPtr));
cudaPtr = nullptr;
nbElements = 0;
}
public:
FCudaData(const FCudaData&) = delete;
FCudaData& operator=(const FCudaData&) = delete;
FCudaData(const ObjectClass* inCpuPtr, const FSize inNbElements)
: cudaPtr(nullptr), nbElements(0){
allocAndCopy(inCpuPtr, inNbElements);
}
FCudaData(FCudaData&& other)
: cudaPtr(nullptr), nbElements(0){
this->cudaPtr = other->cudaPtr;
this->nbElements = other->nbElements;
other->cudaPtr = nullptr;
other->nbElements = 0;
}
FCudaData& operator=(FCudaData&& other){
dealloc();
this->cudaPtr = other->cudaPtr;
this->nbElements = other->nbElements;
other->cudaPtr = nullptr;
other->nbElements = 0;
}
~FCudaData(){
dealloc();
}
void release(){
dealloc();
}
ObjectClass* get() {
return cudaPtr;
}
const ObjectClass* get() const {
return cudaPtr;
}
FSize getSize() const {
return nbElements;
}
void copyToHost(ObjectClass* inCpuPtr){
FCudaCheck( cudaMemcpy( inCpuPtr, cudaPtr, nbElements*sizeof(ObjectClass),
cudaMemcpyDeviceToHost ) );
}
};
#endif // FCUDADATA_HPP
#ifndef FCUDATIC_HPP
#define FCUDATIC_HPP
#include "FCudaGlobal.hpp"
/**
* \brief Time counter class.
* \author Berenger Bramas (berenger.bramas@inria.fr)
*
* This time counter can be (re)started using tic() and stopped using tac().
*
* - use elapsed() to get the last time interval;
* - use cumulated() to get the total running time;
* - use reset() to stop and reset the counter.
*
* \code
* FCudaTic timer;
* timer.tic();
* //...(1)
* timer.tac();
* timer.elapsed(); // time of (1) in s
* timer.tic();
* //...(2)
* timer.tac();
* timer.elapsed(); // time of (2) in s
* timer.cumulated() // time of (1) and (2) in s
* timer.reset() // reset the object
* \endcode
*
*/
class FCudaTic {
private:
cudaStream_t stream;
cudaEvent_t start = 0; ///< start time (tic)
cudaEvent_t end = 0; ///< stop time (tac)
double cumulate = 0; ///< the cumulate time
public:
/// Constructor
explicit FCudaTic(const cudaStream_t inStream = 0)
: stream(inStream){
FCudaCheck(cudaEventCreate(&start));
FCudaCheck(cudaEventCreate(&end));
tic();
}
~FCudaTic(){
FCudaCheck( cudaEventDestroy( start ) );
FCudaCheck( cudaEventDestroy( end ) );
}
/// Copy constructor
FCudaTic(const FCudaTic& other) = delete;
/// Copy operator
FCudaTic& operator=(const FCudaTic& other) = delete;
/// Resets the timer
/**\warning Use tic() to restart the timer. */
void reset() {
cumulate = 0;
}
/// Start measuring time.
void tic(){
FCudaCheck(cudaEventRecord( start, stream ));
}
/// Stop measuring time and add to cumulated time.
void tac(){
FCudaCheck(cudaEventRecord( end, stream ));
FCudaCheck(cudaEventSynchronize( end ));
cumulate += elapsed();
}
/// Elapsed time between the last tic() and tac() (in seconds).
/** \return the time elapsed between tic() & tac() in second. */
double elapsed() const{
float elapsedTime;
FCudaCheck( cudaEventElapsedTime( &elapsedTime, start, end ) ); // in ms
return elapsedTime/1000.0;
}
/// Cumulated tic() - tac() time spans
/** \return the time elapsed between ALL tic() & tac() in second. */
double cumulated() const{
return cumulate;
}
/// Combination of tic() and elapsed().
/** \return the time elapsed between tic() & tac() in second. */
double tacAndElapsed() {
tac();
return elapsed();
}
};
#endif // FCUDATIC_HPP
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment