Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cuBQL/builder/omp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ namespace cuBQL {
void refit(BinaryBVH<T,D> &bvh,
const box_t<T,D> *boxes,
Context *ctx);

template<typename T, int D>
void freeBVH(BinaryBVH<T,D> &bvh,
Context *ctx);
}
}

Expand Down
72 changes: 72 additions & 0 deletions cuBQL/builder/omp/AtomicBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,42 @@ namespace cuBQL {
#endif
}

/*! iw - note: this implementation of atomic min/max via atomic
compare-exchange (CAS); which is cetainly not optimal on any
sort of modern GPU - but it works in any C++-21 compliant
compiler, so it's what we do for now */
inline void atomic_min(double *ptr, double value)
{
#ifdef __NVCOMPILER
# if 1
double &mem = *ptr;
if (mem <= value) return;
while (1) {
double wasBefore;
#pragma omp atomic capture
{ wasBefore = mem; mem = value; }
if (wasBefore >= value) break;
value = wasBefore;
}
# else
double current = *(volatile double *)ptr;
while (current > value) {
bool wasChanged
= ((std::atomic<long long int>*)ptr)
->compare_exchange_weak((long long int&)current,(long long int&)value);
if (wasChanged) break;
}
# endif
#else
double &x = *ptr;
#pragma omp atomic compare
if (x > value) { x = value; }
// double t;
// #pragma omp atomic capture
// { t = *ptr; *ptr = std::min(t,value); }
#endif
}

/*! iw - note: this implementation of atomic min/max via atomic
compare-exchange (CAS); which is cetainly not optimal on any
sort of modern GPU - but it works in any C++-21 compliant
Expand Down Expand Up @@ -96,6 +132,42 @@ namespace cuBQL {
#endif
}

/*! iw - note: this implementation of atomic min/max via atomic
compare-exchange (CAS); which is cetainly not optimal on any
sort of modern GPU - but it works in any C++-21 compliant
compiler, so it's what we do for now */
inline void atomic_max(double *ptr, double value)
{
#ifdef __NVCOMPILER
# if 1
double &mem = *ptr;
if (mem >= value) return;
while (1) {
double wasBefore;
#pragma omp atomic capture
{ wasBefore = mem; mem = value; }
if (wasBefore <= value) break;
value = wasBefore;
}
# else
double current = *(volatile double *)ptr;
while (current < value) {
bool wasChanged
= ((std::atomic<long long int>*)ptr)
->compare_exchange_weak((long long int&)current,(long long int&)value);
if (wasChanged) break;
}
# endif
#else
double &x = *ptr;
#pragma omp atomic compare
if (x < value) { x = value; }
// double t;
// #pragma omp atomic capture
// { t = *ptr; *ptr = std::max(t,value); }
#endif
}

template<typename T, int D>
inline void v_atomic_min(vec_t<T,D> *ptr, vec_t<T,D> v);
template<typename T, int D>
Expand Down
9 changes: 9 additions & 0 deletions cuBQL/builder/omp/spatialMedian.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,15 @@ namespace cuBQL {
cuBQL::omp::refit(bvh,boxes,ctx);
}

template<typename T, int D>
void freeBVH(BinaryBVH<T,D> &bvh,
Context *ctx)
{
ctx->free(bvh.primIDs);
ctx->free(bvh.nodes);
bvh.primIDs = 0;
}

}

template<typename T, int D>
Expand Down