1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include <assert.h>
7 #include "yaksa.h"
8 #include "yaksi.h"
9 #include "yaksu.h"
10 #include "yaksuri.h"
11 
ipup(const void * inbuf,void * outbuf,uintptr_t count,yaksi_type_s * type,yaksi_info_s * info,yaksi_request_s * request)12 static int ipup(const void *inbuf, void *outbuf, uintptr_t count, yaksi_type_s * type,
13                 yaksi_info_s * info, yaksi_request_s * request)
14 {
15     int rc = YAKSA_SUCCESS;
16     yaksuri_request_s *reqpriv = (yaksuri_request_s *) request->backend.priv;
17     yaksuri_info_s *infopriv;
18     int (*hookfn) (const void *inbuf, void *outbuf, yaksi_info_s * info,
19                    yaksur_ptr_attr_s * inattr, yaksur_ptr_attr_s * outattr);
20 
21     if (info) {
22         infopriv = (yaksuri_info_s *) info->backend.priv;
23     }
24 
25     yaksuri_gpudriver_id_e id = reqpriv->gpudriver_id;
26     if (id == YAKSURI_GPUDRIVER_ID__UNSET) {
27         for (id = YAKSURI_GPUDRIVER_ID__UNSET; id < YAKSURI_GPUDRIVER_ID__LAST; id++) {
28             if (id == YAKSURI_GPUDRIVER_ID__UNSET || yaksuri_global.gpudriver[id].hooks == NULL)
29                 continue;
30 
31             if (info && infopriv->gpudriver_id != YAKSURI_GPUDRIVER_ID__UNSET &&
32                 infopriv->gpudriver_id != id)
33                 continue;
34 
35             hookfn = yaksuri_global.gpudriver[id].hooks->get_ptr_attr;
36             if (reqpriv->optype == YAKSURI_OPTYPE__PACK) {
37                 rc = hookfn((const char *) inbuf + type->true_lb, outbuf, info,
38                             &request->backend.inattr, &request->backend.outattr);
39             } else {
40                 rc = hookfn(inbuf, (char *) outbuf + type->true_lb, info,
41                             &request->backend.inattr, &request->backend.outattr);
42             }
43             YAKSU_ERR_CHECK(rc, fn_fail);
44 
45             if (request->backend.inattr.type == YAKSUR_PTR_TYPE__GPU ||
46                 request->backend.outattr.type == YAKSUR_PTR_TYPE__GPU) {
47                 reqpriv->gpudriver_id = id;
48                 break;
49             }
50         }
51     }
52 
53     if (id == YAKSURI_GPUDRIVER_ID__LAST)
54         reqpriv->gpudriver_id = YAKSURI_GPUDRIVER_ID__UNSET;
55 
56     /* if this can be handled by the CPU, wrap it up */
57     if (reqpriv->gpudriver_id == YAKSURI_GPUDRIVER_ID__UNSET) {
58         bool is_supported;
59         rc = yaksuri_seq_pup_is_supported(type, &is_supported);
60         YAKSU_ERR_CHECK(rc, fn_fail);
61 
62         if (!is_supported) {
63             rc = YAKSA_ERR__NOT_SUPPORTED;
64         } else {
65             if (reqpriv->optype == YAKSURI_OPTYPE__PACK) {
66                 rc = yaksuri_seq_ipack(inbuf, outbuf, count, type, info);
67                 YAKSU_ERR_CHECK(rc, fn_fail);
68             } else {
69                 rc = yaksuri_seq_iunpack(inbuf, outbuf, count, type, info);
70                 YAKSU_ERR_CHECK(rc, fn_fail);
71             }
72         }
73         goto fn_exit;
74     }
75 
76     /* if this cannot be handled by the CPU, queue it up for the GPU
77      * to handle */
78     assert(reqpriv->gpudriver_id != YAKSURI_GPUDRIVER_ID__UNSET);
79 
80     rc = yaksuri_progress_enqueue(inbuf, outbuf, count, type, info, request);
81     YAKSU_ERR_CHECK(rc, fn_fail);
82 
83   fn_exit:
84     return rc;
85   fn_fail:
86     goto fn_exit;
87 }
88 
yaksur_ipack(const void * inbuf,void * outbuf,uintptr_t count,yaksi_type_s * type,yaksi_info_s * info,yaksi_request_s * request)89 int yaksur_ipack(const void *inbuf, void *outbuf, uintptr_t count, yaksi_type_s * type,
90                  yaksi_info_s * info, yaksi_request_s * request)
91 {
92     int rc = YAKSA_SUCCESS;
93     yaksuri_request_s *reqpriv = (yaksuri_request_s *) request->backend.priv;
94 
95     reqpriv->optype = YAKSURI_OPTYPE__PACK;
96     rc = ipup(inbuf, outbuf, count, type, info, request);
97     YAKSU_ERR_CHECK(rc, fn_fail);
98 
99   fn_exit:
100     return rc;
101   fn_fail:
102     goto fn_exit;
103 }
104 
yaksur_iunpack(const void * inbuf,void * outbuf,uintptr_t count,yaksi_type_s * type,yaksi_info_s * info,yaksi_request_s * request)105 int yaksur_iunpack(const void *inbuf, void *outbuf, uintptr_t count, yaksi_type_s * type,
106                    yaksi_info_s * info, yaksi_request_s * request)
107 {
108     int rc = YAKSA_SUCCESS;
109     yaksuri_request_s *reqpriv = (yaksuri_request_s *) request->backend.priv;
110 
111     reqpriv->optype = YAKSURI_OPTYPE__UNPACK;
112     rc = ipup(inbuf, outbuf, count, type, info, request);
113     YAKSU_ERR_CHECK(rc, fn_fail);
114 
115   fn_exit:
116     return rc;
117   fn_fail:
118     goto fn_exit;
119 }
120