{"id":2554,"date":"2017-11-19T20:40:21","date_gmt":"2017-11-19T20:40:21","guid":{"rendered":"http:\/\/www.colorwave.it\/blog\/?p=2554"},"modified":"2018-01-29T06:25:45","modified_gmt":"2018-01-29T06:25:45","slug":"gpu_mem_object","status":"publish","type":"post","link":"https:\/\/www.colorwave.it\/blog\/framework\/gpu_mem_object\/admin\/2017\/11\/","title":{"rendered":"gpu_mem_object"},"content":{"rendered":"<p>La <em>gpu_mem_object<\/em> \u00e8 la classe base di gestione degli oggetti di memoria creati su un context OpenCL:\u00a0 da essa derivano tutte le classi di\u00a0 i\/o di dati verso i kernel; <em>gpu_mem_object<\/em>\u00a0 gestisce alcune propriet\u00e0 comuni e definisce le funzioni virtuali, che possono essere riscritte per le classi derivate.<\/p>\n<h4>Perch\u00e8 questa classe?<\/h4>\n<p>la definizione del passaggio di parametri ad un kernel pu\u00f2 essere particolarmente complesso, dovendo spesso trasferire e\/o ricevere dati la cui sequenza pu\u00f2 essere onerosa da gestire; le classi derivate da\u00a0<em>gpu_mem_object <\/em>sono state progettate per standardizzare le modalit\u00e0 di i\/o su un kernel, quando le informazioni gestite dalle classi sono usate frequentemente in molti differenti kernel; ad esempio la classe <em>gpu_lut_rgb<\/em> definisce un modo standardizzato per trasferire ad un kernel tutte le informazioni (in questo caso numero di elementi nella lut, numero di indici e dimensioni degli elementi); Vedremo che il trasferimento al kernel viene effettuato attraverso una funzione virtuale <em>Push_kernel<\/em>, prima dell&#8217;esecuzione dello stesso. Baster\u00e0 quindi, per ciascuna classe derivata riscrivere questa funzione e documentarne la sequenza di parametri generata nel commento.<\/p>\n<pre class=\"lang:default decode:true \">\/** \\brief classe prototipo di tutti gli oggetti memoria di opencl\r\n*\/\r\nclass AFX_EXT_CLASS gpu_mem_object\r\n{\r\npublic:\r\n\tgpu_mem_object ( );\r\n\tvirtual ~gpu_mem_object ( );\r\n\r\n\t\/** assegna l'handler opencl\r\n\t*\/\r\n\tvoid Set_id ( cl_mem _cl_mem );\r\n\r\n\t\/** rimanda l'handler opencl\r\n\t*\/\r\n\tcl_mem Get_id ( );\r\n\r\n\tvoid Set_kernel ( class gpu_kernel *kernel );\r\n\tgpu_kernel *Get_kernel ( );\r\n\r\n\t\/** \\brief definisce i flag di modalit\u00e0 memoria gpu gestita\r\n\t\\details CL_MEM_READ_ONLY.. etc\r\n\t*\/\r\n\tbool Set_mem_flags ( cl_mem_flags mode );\r\n\r\n\t\/** \\brief rimanda i flag di modalit\u00e0 memoria gpu gestita\r\n\t*\/\r\n\tcl_mem_flags Get_mem_flags ( );\r\n\r\n\t\/** \\brief rimanda il puntatore alla memoria allocata nella CPU\r\n\t*\/\r\n\tvirtual void *Ptr ( );\r\n\r\n\t\/**  quantit\u00e0 di memoria assegnata al puntatore\r\n\t*\/\r\n\tvirtual size_t Bytes ( );\r\n\r\n\t\/** \\brief trasferisce i dati dell'oggetto al kernel \r\n\t\\details la  funzione \u00e8 virtuale e deve essere ridefinita per ciascun oggetto derivato\r\n\til kernel che riceve la struttur\u00e0 sar\u00e0 ovviamente scritto in modo\r\n\tda intercettare correttamente i parametri passati per\r\n\tciascuna classe.\r\n\tFare riferimento alla descrizione di ciascuna classe derivata per la conoscenza\r\n\tdei parametri trasferiti al kernel\r\n\r\n\t\\param kernel se ==0 trasferisce \u00e8 il kernel dove trasferire, altrimenti usa il kernel assegnato\r\n\r\n\t\\return true se informazione da trasferire correttamente definita\r\n\t*\/\r\n\tvirtual bool Push_kernel(gpu_kernel *kernel=0);\r\n\r\n\tpublic: _gpu_object_code c_gpu_mem;\t\/\/ codice oggetto memoria assegnato\r\n\r\n\t__use_private_struct\r\n};\r\n<\/pre>\n<h4>Set_id\u00a0 e Get_id<\/h4>\n<p>Le due funzioni permettono di assegnare e ottenere l&#8217;handle\u00a0 \u00a0cl_mem ottenuto da OpenCL quando viene creato un oggetto di memoria (buffer, immagine etc) ; ricordiamo che un oggetto\u00a0 di memoria \u00e8 sempre creato e assegnato a un <em>gpu_context ; i<\/em>n particolare la funzione Set_Id() \u00e8 usata internamente dalla gpu_context quando viene richiesta la creazione di un qualunque oggetto\u00a0<em>gpu_mem_object, <\/em>pertanto non deve essere normalmente utilizzato dalle classi derivate.<\/p>\n<h4>Set_kernel<\/h4>\n<p>Definisce il gpu_kernel al quale sar\u00e0 trasferito l&#8217;elemento\u00a0<em>gpu_mem_object.\u00a0<\/em>Vedremo in un prossimo articolo come e dove utilizzare questa funzione.<\/p>\n<div class=\"sparklegrid row\"><div class=\"col-sparkle-16 sparkle-grid\"><img decoding=\"async\" data-attachment-id=\"283\" data-permalink=\"https:\/\/www.colorwave.it\/blog\/framework\/linterfaccia-operation_call\/admin\/2015\/05\/attachment\/fumetto\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?fit=24%2C24&amp;ssl=1\" data-orig-size=\"24,24\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"fumetto\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?fit=24%2C24&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?fit=24%2C24&amp;ssl=1\" tabindex=\"0\" role=\"button\" class=\"size-full wp-image-283 alignleft\" src=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?resize=24%2C24&#038;ssl=1\" alt=\"\" width=\"24\" height=\"24\" data-recalc-dims=\"1\" \/><\/p><\/div><\/div>\n<p>Il kernel assegnato con questa funzione \u00e8 quello di default; vedremo che comunque sar\u00e0 possibile passare l&#8217;oggetto <em>gpu_mem_object<\/em> a pi\u00f9 kernel da eseguire in parallelo.<\/p>\n<h4>Get_ker<strong>nel<\/strong><\/h4>\n<p>rimanda la classe gpu_kernel che \u00e8 stata assegnata di default;<\/p>\n<h4>Set_mem_flags e\u00a0Get_mem_flags<\/h4>\n<p>Le due funzioni, gestite internamente al gpu_context definiscono le modalit\u00e0 di gestione dell&#8217;oggetto passato al kernel; i valori sono quelli assegnabili al tipo\u00a0 enumerato cl_mem_flags (CL_MEM_READ_ONLY CL_MEM_WRITE_ONLY.. etc). Per una lista completa dei valori dei tipi enumerati di OpenCL <a href=\"https:\/\/www.khronos.org\/registry\/OpenCL\/sdk\/1.0\/docs\/man\/xhtml\/enums.html\">leggere qui<\/a>.<\/p>\n<h4 id=\"crayon-5a39709028888858288551-31\" class=\"crayon-line\"><span class=\"crayon-e\">virtual <\/span><span class=\"crayon-t\">void<\/span> <span class=\"crayon-o\">*<\/span><span class=\"crayon-e\">Ptr<\/span><\/h4>\n<div id=\"crayon-5a39709028888858288551-29\" class=\"crayon-line\"><span class=\"crayon-c\">Rimanda il puntatore alla memoria allocata\/assegnata nella classe; La funzione \u00e8 virtuale, poich\u00e9 le classi derivate devono poter gestire dati e schemi di memoria differenti; la classe base gpu_mem_object rimanda 0, poich\u00e8 non \u00e8 deputata a gestire direttamente i puntatore, ma fornisce lo schema per le classi derivate.<\/span><\/div>\n<h4>virtual size_t Bytes<\/h4>\n<p>Rimanda la quantit\u00e0 in bytes allocata con il puntatore rimandato da Ptr(); Come la funzione Ptr(), anche la Bytes() pu\u00f2 essere usata per accedere, quando necessario, alla memoria di i\/o sul kernel; ad esempio si pu\u00f2 accedere alla memoria di un oggetto modificato dal\u00a0 kernel (ad esempio la memoria di in oggetto IMAGE passato al kernel utilizzando la gpu_image_2d..)<\/p>\n<h4>virtual bool Push_kernel<\/h4>\n<p>La funzione, riscritta per ciascuna classe derivata da gpu_mem_object, ha il compito di trasferire le immagini nella coda del kernel; vedremo in seguito un esempio di costruzione di questa funzione; Notare che il kernel di esecuzione passato alla funzione pu\u00f2 essere diverso da quello dichiarato di default; in questo caso ci si aspetta che il nuovo kernel (o i nuovi..) sia in parallelo con quello di default;<\/p>\n<div class=\"sparklegrid row\"><div class=\"col-sparkle-16 sparkle-grid\"><img decoding=\"async\" data-attachment-id=\"283\" data-permalink=\"https:\/\/www.colorwave.it\/blog\/framework\/linterfaccia-operation_call\/admin\/2015\/05\/attachment\/fumetto\/\" data-orig-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?fit=24%2C24&amp;ssl=1\" data-orig-size=\"24,24\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"fumetto\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?fit=24%2C24&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?fit=24%2C24&amp;ssl=1\" tabindex=\"0\" role=\"button\" class=\"size-full wp-image-283 alignleft\" src=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2015\/05\/fumetto.png?resize=24%2C24&#038;ssl=1\" alt=\"\" width=\"24\" height=\"24\" data-recalc-dims=\"1\" \/><\/p><\/div><\/div>\n<p>Il kernel passato per default \u00e8 stato definito per semplificare la scrittura dei programmi da eseguire su OpenCL: il gpu_context di allocazione dei gpu_mem_object deve necessariamente essere lo stesso per tutti i kernel, quindi verr\u00e0 ricavato dalla prima assegnazione, ricavandolo dal primo gpu_kernel. Il pi\u00f9 delle volte succeder\u00e0 di definire programmi che usano un solo kernel o li usano in modo sequenziale; in questo caso vedremo che questa strategia di scrittura favorisce la concisione,\u00a0 nascondendo molti passaggi e chiamate a funzioni OpenCL che altrimenti dovrebbero comunque essere effettuate.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>La gpu_mem_object \u00e8 la classe base di gestione degli oggetti di memoria creati su un context OpenCL:\u00a0 da essa derivano tutte le classi di\u00a0 i\/o di dati verso i kernel; gpu_mem_object\u00a0 gestisce alcune propriet\u00e0 comuni e definisce le funzioni virtuali, che possono&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"aside","meta":{"_acf_changed":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false,"jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[19,29,108],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9rwsf-Fc","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/2554"}],"collection":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/comments?post=2554"}],"version-history":[{"count":15,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/2554\/revisions"}],"predecessor-version":[{"id":2570,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/2554\/revisions\/2570"}],"wp:attachment":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/media?parent=2554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/categories?post=2554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/tags?post=2554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}