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 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 < num_input_fields; i++) { 72 ierr = CeedVectorRestoreArrayRead(U[i], &data->fields.inputs[i]); 73 CeedChkBackend(ierr); 74 } 75 for (CeedInt i = 0; i < num_output_fields; 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 101 return CEED_ERROR_SUCCESS; 102 } 103 104 //------------------------------------------------------------------------------ 105 // Create QFunction 106 //------------------------------------------------------------------------------ 107 int CeedQFunctionCreate_Hip(CeedQFunction qf) { 108 int ierr; 109 Ceed ceed; 110 CeedQFunctionGetCeed(qf, &ceed); 111 CeedQFunction_Hip *data; 112 ierr = CeedCalloc(1,&data); CeedChkBackend(ierr); 113 ierr = CeedQFunctionSetData(qf, data); CeedChkBackend(ierr); 114 CeedInt num_input_fields, num_output_fields; 115 ierr = CeedQFunctionGetNumArgs(qf, &num_input_fields, &num_output_fields); 116 CeedChkBackend(ierr); 117 118 // Read QFunction source 119 ierr = CeedQFunctionGetKernelName(qf, &data->qfunction_name); 120 CeedChkBackend(ierr); 121 ierr = CeedQFunctionLoadSourceToBuffer(qf, &data->qfunction_source); 122 CeedChkBackend(ierr); 123 124 // Register backend functions 125 ierr = CeedSetBackendFunction(ceed, "QFunction", qf, "Apply", 126 CeedQFunctionApply_Hip); CeedChkBackend(ierr); 127 ierr = CeedSetBackendFunction(ceed, "QFunction", qf, "Destroy", 128 CeedQFunctionDestroy_Hip); CeedChkBackend(ierr); 129 return CEED_ERROR_SUCCESS; 130 } 131 //------------------------------------------------------------------------------ 132