OBJS = incrementf90 incrementcuf multiblock multidim explicitInterface \
       managed managedImplicit multidimCUF managedCUF \
       managedCUF2f90 managedCUF2cuf deviceQuery pciBusID \
       errorHandling syncError asyncError version

# asyncError deliberately writes through an unallocated device pointer, which
# leaves the CUDA context in an error state; whether the program still exits 0
# afterwards depends on the platform (it aborts on aarch64), so it is built but not run
RUNOBJS = $(filter-out asyncError,$(OBJS))

all: build run verify

build: $(OBJS)

run: build
	@for x in $(RUNOBJS); do \
	  echo "----------------- $$x --------------------"; \
	  $(RUN) ./$$x || exit 1; \
	done

verify:

# section 1.3.1

incrementf90: increment.f90
	nvfortran -o $@ $<

incrementcuf: increment.cuf
	nvfortran -o $@ $<

# section 1.3.2

multiblock: multiblock.cuf 
	nvfortran -o $@ $<

# section 1.3.3

multidim: multidim.cuf
	nvfortran -o $@ $<

# section 1.3.4

explicitInterface: explicitInterface.cuf
	nvfortran -o $@ $<

# section 1.3.5

managed: managed.cuf
	nvfortran -o $@ $<

managedImplicit: managedImplicit.cuf
	nvfortran -o $@ -gpu=mem:managed $<

# section 1.3.6

multidimCUF: multidimCUF.cuf
	nvfortran -o $@ $<

managedCUF: managedCUF.cuf
	nvfortran -o $@ $<

managedCUF2f90: managedCUF2.f90
	nvfortran -o $@ $<

managedCUF2cuf: managedCUF2.f90
	nvfortran -o $@ -cuda $<

# section 1.4

deviceQuery: deviceQuery.cuf
	nvfortran -o $@ $<

# section 1.4.1

pciBusID: pciBusID.cuf
	nvfortran -o $@ $<

# section 1.5

errorHandling: errorHandling.cuf
	nvfortran -o $@ $<

syncError: syncError.cuf
	nvfortran -o $@ $<

asyncError: asyncError.cuf
	nvfortran -o $@ $<

# section 1.7

version: version.cuf
	nvfortran -o $@ $<

clean:
	rm -rf $(OBJS) *.o *.mod *~
