Skip to content

Commit f6956c6

Browse files
authored
Merge pull request #863 from danielpeter/devel
updates cuda device properties, and NaN checks for EMC models
2 parents 118d7af + b32c591 commit f6956c6

4 files changed

Lines changed: 72 additions & 9 deletions

File tree

src/gpu/initialize_gpu.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,16 @@ static void output_cuda_device_infos(int myrank){
350350
}else{
351351
fprintf(fp," canMapHostMemory: FALSE\n");
352352
}
353-
if (deviceProp.deviceOverlap) {
353+
#if CUDA_VERSION < 13000 || (defined (__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ < 13))
354+
if (deviceProp.deviceOverlap){
354355
fprintf(fp," deviceOverlap: TRUE\n");
355356
}else{
356357
fprintf(fp," deviceOverlap: FALSE\n");
357358
}
359+
#else
360+
// CUDA version >= 13, deviceOverlap deprecated, replaced by asyncEngineCount
361+
fprintf(fp," asyncEngineCount: %d\n", deviceProp.asyncEngineCount);
362+
#endif
358363
if (deviceProp.concurrentKernels) {
359364
fprintf(fp," concurrentKernels: TRUE\n");
360365
}else{

src/meshfem3D/model_EMC.f90

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,8 @@ end subroutine check_dimorder
716716
! --------------------------------
717717
subroutine check_variable_attributes(ncid, varid, unit, direction, missing_val)
718718

719+
use, intrinsic :: ieee_arithmetic
720+
719721
implicit none
720722
integer, intent(in) :: ncid
721723
integer, intent(in) :: varid
@@ -724,14 +726,18 @@ subroutine check_variable_attributes(ncid, varid, unit, direction, missing_val)
724726
! local parameters
725727
integer :: num_atts,i
726728
character(len=100) :: name,value
727-
real(kind=CUSTOM_REAL) :: fill_val
729+
real(kind=CUSTOM_REAL) :: fill_val,val_read
728730
logical :: has_fill_value,has_missing_value
729731

732+
! note: isNaN() function is a GNU extension, thus not all compilers might have it.
733+
! using a simple val /= val check can already work.
734+
! here, we double-check with the IEEE intrinsic function ieee_is_nan() which should be Fortran2003 standard.
735+
730736
! initializes
731737
unit = 0
732738
direction = 0
733-
missing_val = 9999.0_CUSTOM_REAL
734-
fill_val = 9999.0_CUSTOM_REAL
739+
missing_val = 99999.0_CUSTOM_REAL ! initializes to some ficticious value
740+
fill_val = 99999.0_CUSTOM_REAL
735741

736742
has_missing_value = .false.
737743
has_fill_value = .false.
@@ -804,22 +810,47 @@ subroutine check_variable_attributes(ncid, varid, unit, direction, missing_val)
804810
endif
805811

806812
else if (trim(name) == 'missing_value') then
813+
! initialize to avoid issues with netcdf function call
814+
val_read = 0.0_CUSTOM_REAL
807815
! assigns value for invalid entries
808-
call check_status(nf90_get_att(ncid, varid, name, missing_val))
809-
if (VERBOSE) print *,' missing value: ',missing_val
816+
call check_status(nf90_get_att(ncid, varid, name, val_read))
817+
if (VERBOSE) print *,' missing value: ',val_read
818+
! to avoid compiler running into floating-point invalid errors, we double-check if value is not-a-number
810819
has_missing_value = .true.
820+
! isNaN check
821+
if (val_read /= val_read) then
822+
! NaN value
823+
has_missing_value = .false.
824+
else
825+
has_missing_value = .true.
826+
endif
827+
! double-check with ieee function
828+
if (ieee_support_standard(val_read)) then
829+
if (ieee_is_nan(val_read)) has_missing_value = .false.
830+
endif
831+
! only assign if not NaN
832+
if (has_missing_value) missing_val = val_read
811833

812834
else if (trim(name) == '_FillValue' .or. trim(name) == 'FillValue') then
835+
! initialize to avoid issues with netcdf function call
836+
val_read = 0.0_CUSTOM_REAL
813837
! assigns value for invalid entries
814-
call check_status(nf90_get_att(ncid, varid, name, fill_val))
815-
if (VERBOSE) print *,' fill value: ',fill_val
838+
call check_status(nf90_get_att(ncid, varid, name, val_read))
839+
if (VERBOSE) print *,' fill value: ',val_read
840+
! to avoid compiler running into floating-point invalid errors, we double-check if value is not-a-number
841+
has_fill_value = .true.
816842
! isNaN check
817-
if (fill_val /= fill_val) then
843+
if (val_read /= val_read) then
818844
! NaN value
819845
has_fill_value = .false.
820846
else
821847
has_fill_value = .true.
822848
endif
849+
! double-check with ieee function
850+
if (ieee_support_standard(val_read)) then
851+
if (ieee_is_nan(val_read)) has_fill_value = .false.
852+
endif
853+
if (has_fill_value) fill_val = val_read
823854

824855
else if (trim(name) == 'long_name' .or. trim(name) == '_long_name') then
825856
! assigns value for invalid entries
@@ -2887,6 +2918,22 @@ subroutine read_emc_model()
28872918
double precision, parameter :: RCMB_ = 3480000.d0
28882919
double precision, parameter :: R_EARTH_ = 6371000.d0
28892920

2921+
! initializes
2922+
dir_dep = 0
2923+
dir = 0
2924+
2925+
missing_val_vp = 99999.0_CUSTOM_REAL ! initializes to some ficticious value
2926+
missing_val_vs = 99999.0_CUSTOM_REAL
2927+
missing_val_rho = 99999.0_CUSTOM_REAL
2928+
missing_val_dep = 99999.0_CUSTOM_REAL
2929+
2930+
missing_val_vpv = 99999.0_CUSTOM_REAL
2931+
missing_val_vph = 99999.0_CUSTOM_REAL
2932+
missing_val_vsv = 99999.0_CUSTOM_REAL
2933+
missing_val_vsh = 99999.0_CUSTOM_REAL
2934+
missing_val_eta = 99999.0_CUSTOM_REAL
2935+
missing_val_qmu = 99999.0_CUSTOM_REAL
2936+
28902937
if (VERBOSE) print *,'reading EMC model:'
28912938

28922939
! Open netcdf file with write access

utils/GPU_tools/check_cuda_device.cu

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,16 @@ e.g., on titan enable environment CRAY_CUDA_MPS=1 to use a single GPU with multi
282282
}else{
283283
printf(" canMapHostMemory: FALSE\n");
284284
}
285+
#if CUDA_VERSION < 13000 || (defined (__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ < 13))
285286
if(deviceProp.deviceOverlap){
286287
printf(" deviceOverlap: TRUE\n");
287288
}else{
288289
printf(" deviceOverlap: FALSE\n");
289290
}
291+
#else
292+
// CUDA version >= 13, deviceOverlap deprecated, replaced by asyncEngineCount
293+
printf(" asyncEngineCount: %d\n", deviceProp.asyncEngineCount);
294+
#endif
290295
fflush(stdout);
291296

292297

utils/infos/fault_tolerance_FTI_Leonardo_Bautista_Gomez/specfem3D_globe_simple_demo_code_for_GPUs_in_C_and_CUDA_with_fault_tolerance_library_nov2011.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,16 @@ int main(int argc, char *argv[])
207207
else
208208
{ printf("canMapHostMemory: FALSE\n"); }
209209

210+
#if CUDA_VERSION < 13000 || (defined (__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ < 13))
210211
if(deviceProp.deviceOverlap)
211212
{ printf("deviceOverlap: TRUE\n"); }
212213
else
213214
{ printf("deviceOverlap: FALSE\n"); }
215+
#else
216+
// CUDA version >= 13, deviceOverlap deprecated, replaced by asyncEngineCount
217+
printf(" asyncEngineCount: %d\n", deviceProp.asyncEngineCount);
218+
#endif
219+
214220
#endif
215221

216222
// make sure that the device has compute capability >= 1.3

0 commit comments

Comments
 (0)