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 num_input_fields, num_output_fields; 43 ierr = CeedQFunctionGetNumArgs(qf, &num_input_fields, &num_output_fields); 44 CeedChkBackend(ierr); 45 const int blocksize = ceed_Hip->opt_block_size; 46 47 // Read vectors 48 for (CeedInt i = 0; i < num_input_fields; i++) { 49 ierr = CeedVectorGetArrayRead(U[i], CEED_MEM_DEVICE, &data->fields.inputs[i]); 50 CeedChkBackend(ierr); 51 } 52 for (CeedInt i = 0; i < num_output_fields; i++) { 53 ierr = CeedVectorGetArrayWrite(V[i], CEED_MEM_DEVICE, &data->fields.outputs[i]); 54 CeedChkBackend(ierr); 55 } 56 57 // Get context data 58 ierr = CeedQFunctionGetInnerContextData(qf, CEED_MEM_DEVICE, &data->d_c); 59 CeedChkBackend(ierr); 60 61 // Run kernel 62 void *args[] = {&data->d_c, (void *) &Q, &data->fields}; 63 ierr = CeedRunKernelHip(ceed, data->QFunction, CeedDivUpInt(Q, blocksize), 64 blocksize, args); CeedChkBackend(ierr); 65 66 // Restore vectors 67 for (CeedInt i = 0; i < num_input_fields; i++) { 68 ierr = CeedVectorRestoreArrayRead(U[i], &data->fields.inputs[i]); 69 CeedChkBackend(ierr); 70 } 71 for (CeedInt i = 0; i < num_output_fields; i++) { 72 ierr = CeedVectorRestoreArray(V[i], &data->fields.outputs[i]); 73 CeedChkBackend(ierr); 74 } 75 76 // Restore context 77 ierr = CeedQFunctionRestoreInnerContextData(qf, &data->d_c); 78 CeedChkBackend(ierr); 79 80 return CEED_ERROR_SUCCESS; 81 } 82 83 //------------------------------------------------------------------------------ 84 // Destroy QFunction 85 //------------------------------------------------------------------------------ 86 static int CeedQFunctionDestroy_Hip(CeedQFunction qf) { 87 int ierr; 88 CeedQFunction_Hip *data; 89 ierr = CeedQFunctionGetData(qf, &data); CeedChkBackend(ierr); 90 Ceed ceed; 91 ierr = CeedQFunctionGetCeed(qf, &ceed); CeedChkBackend(ierr); 92 if (data->module) 93 CeedChk_Hip(ceed, hipModuleUnload(data->module)); 94 ierr = CeedFree(&data); CeedChkBackend(ierr); 95 96 return CEED_ERROR_SUCCESS; 97 } 98 99 //------------------------------------------------------------------------------ 100 // Create QFunction 101 //------------------------------------------------------------------------------ 102 int CeedQFunctionCreate_Hip(CeedQFunction qf) { 103 int ierr; 104 Ceed ceed; 105 CeedQFunctionGetCeed(qf, &ceed); 106 CeedQFunction_Hip *data; 107 ierr = CeedCalloc(1,&data); CeedChkBackend(ierr); 108 ierr = CeedQFunctionSetData(qf, data); CeedChkBackend(ierr); 109 CeedInt num_input_fields, num_output_fields; 110 ierr = CeedQFunctionGetNumArgs(qf, &num_input_fields, &num_output_fields); 111 CeedChkBackend(ierr); 112 113 // Read QFunction source 114 ierr = CeedQFunctionGetKernelName(qf, &data->qfunction_name); 115 CeedChkBackend(ierr); 116 CeedDebug256(ceed, 2, "----- Loading QFunction User Source -----\n"); 117 ierr = CeedQFunctionLoadSourceToBuffer(qf, &data->qfunction_source); 118 CeedChkBackend(ierr); 119 CeedDebug256(ceed, 2, "----- Loading QFunction User Source Complete! -----\n"); 120 121 // Register backend functions 122 ierr = CeedSetBackendFunction(ceed, "QFunction", qf, "Apply", 123 CeedQFunctionApply_Hip); CeedChkBackend(ierr); 124 ierr = CeedSetBackendFunction(ceed, "QFunction", qf, "Destroy", 125 CeedQFunctionDestroy_Hip); CeedChkBackend(ierr); 126 return CEED_ERROR_SUCCESS; 127 } 128 //------------------------------------------------------------------------------ 129