1 // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 2 // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 3 // All Rights reserved. See files LICENSE and NOTICE for details. 4 // 5 // This file is part of CEED, a collection of benchmarks, miniapps, software 6 // libraries and APIs for efficient high-order finite element and spectral 7 // element discretizations for exascale applications. For more information and 8 // source code availability see http://github.com/ceed. 9 // 10 // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11 // a collaborative effort of two U.S. Department of Energy organizations (Office 12 // of Science and the National Nuclear Security Administration) responsible for 13 // the planning and preparation of a capable exascale ecosystem, including 14 // software, applications, hardware, advanced system engineering and early 15 // testbed platforms, in support of the nation's exascale computing imperative. 16 17 #include <ceed/ceed.h> 18 #include <ceed/backend.h> 19 #include <hip/hip_runtime.h> 20 #include <stdio.h> 21 #include <string.h> 22 #include "ceed-hip-ref.h" 23 #include "ceed-hip-ref-qfunction-load.h" 24 #include "../hip/ceed-hip-compile.h" 25 26 //------------------------------------------------------------------------------ 27 // Apply QFunction 28 //------------------------------------------------------------------------------ 29 static int CeedQFunctionApply_Hip(CeedQFunction qf, CeedInt Q, 30 CeedVector *U, CeedVector *V) { 31 int ierr; 32 Ceed ceed; 33 ierr = CeedQFunctionGetCeed(qf, &ceed); CeedChkBackend(ierr); 34 35 // Build and compile kernel, if not done 36 ierr = CeedHipBuildQFunction(qf); CeedChkBackend(ierr); 37 38 CeedQFunction_Hip *data; 39 ierr = CeedQFunctionGetData(qf, &data); CeedChkBackend(ierr); 40 Ceed_Hip *ceed_Hip; 41 ierr = CeedGetData(ceed, &ceed_Hip); CeedChkBackend(ierr); 42 CeedInt numinputfields, numoutputfields; 43 ierr = CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 44 CeedChkBackend(ierr); 45 const int blocksize = ceed_Hip->opt_block_size; 46 47 // Read vectors 48 for (CeedInt i = 0; i < numinputfields; i++) { 49 ierr = CeedVectorGetArrayRead(U[i], CEED_MEM_DEVICE, &data->fields.inputs[i]); 50 CeedChkBackend(ierr); 51 } 52 for (CeedInt i = 0; i < numoutputfields; i++) { 53 ierr = CeedVectorGetArrayWrite(V[i], CEED_MEM_DEVICE, &data->fields.outputs[i]); 54 CeedChkBackend(ierr); 55 } 56 57 // Get context data 58 CeedQFunctionContext ctx; 59 ierr = CeedQFunctionGetInnerContext(qf, &ctx); CeedChkBackend(ierr); 60 if (ctx) { 61 ierr = CeedQFunctionContextGetData(ctx, CEED_MEM_DEVICE, &data->d_c); 62 CeedChkBackend(ierr); 63 } 64 65 // Run kernel 66 void *args[] = {&data->d_c, (void *) &Q, &data->fields}; 67 ierr = CeedRunKernelHip(ceed, data->qFunction, CeedDivUpInt(Q, blocksize), 68 blocksize, args); CeedChkBackend(ierr); 69 70 // Restore vectors 71 for (CeedInt i = 0; i < numinputfields; i++) { 72 ierr = CeedVectorRestoreArrayRead(U[i], &data->fields.inputs[i]); 73 CeedChkBackend(ierr); 74 } 75 for (CeedInt i = 0; i < numoutputfields; i++) { 76 ierr = CeedVectorRestoreArray(V[i], &data->fields.outputs[i]); 77 CeedChkBackend(ierr); 78 } 79 80 // Restore context 81 if (ctx) { 82 ierr = CeedQFunctionContextRestoreData(ctx, &data->d_c); 83 CeedChkBackend(ierr); 84 } 85 return CEED_ERROR_SUCCESS; 86 } 87 88 //------------------------------------------------------------------------------ 89 // Destroy QFunction 90 //------------------------------------------------------------------------------ 91 static int CeedQFunctionDestroy_Hip(CeedQFunction qf) { 92 int ierr; 93 CeedQFunction_Hip *data; 94 ierr = CeedQFunctionGetData(qf, &data); CeedChkBackend(ierr); 95 Ceed ceed; 96 ierr = CeedQFunctionGetCeed(qf, &ceed); CeedChkBackend(ierr); 97 if (data->module) 98 CeedChk_Hip(ceed, hipModuleUnload(data->module)); 99 ierr = CeedFree(&data); CeedChkBackend(ierr); 100 return CEED_ERROR_SUCCESS; 101 } 102 103 //------------------------------------------------------------------------------ 104 // Create QFunction 105 //------------------------------------------------------------------------------ 106 int CeedQFunctionCreate_Hip(CeedQFunction qf) { 107 int ierr; 108 Ceed ceed; 109 CeedQFunctionGetCeed(qf, &ceed); 110 CeedQFunction_Hip *data; 111 ierr = CeedCalloc(1,&data); CeedChkBackend(ierr); 112 ierr = CeedQFunctionSetData(qf, data); CeedChkBackend(ierr); 113 CeedInt numinputfields, numoutputfields; 114 ierr = CeedQFunctionGetNumArgs(qf, &numinputfields, &numoutputfields); 115 CeedChkBackend(ierr); 116 117 // Read QFunction source 118 ierr = CeedQFunctionGetKernelName(qf, &data->qFunctionName); 119 CeedChkBackend(ierr); 120 ierr = CeedQFunctionLoadSourceToBuffer(qf, &data->qFunctionSource); 121 CeedChkBackend(ierr); 122 123 // Register backend functions 124 ierr = CeedSetBackendFunction(ceed, "QFunction", qf, "Apply", 125 CeedQFunctionApply_Hip); CeedChkBackend(ierr); 126 ierr = CeedSetBackendFunction(ceed, "QFunction", qf, "Destroy", 127 CeedQFunctionDestroy_Hip); CeedChkBackend(ierr); 128 return CEED_ERROR_SUCCESS; 129 } 130 //------------------------------------------------------------------------------ 131