arrow-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From w...@apache.org
Subject [arrow] branch master updated: ARROW-1802: [GLib] Support arrow-gpu
Date Tue, 14 Nov 2017 03:54:06 GMT
This is an automated email from the ASF dual-hosted git repository.

wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f2d152  ARROW-1802: [GLib] Support arrow-gpu
8f2d152 is described below

commit 8f2d15256d6b3a9da569797f363518abf50d23f5
Author: Kouhei Sutou <kou@clear-code.com>
AuthorDate: Mon Nov 13 22:53:58 2017 -0500

    ARROW-1802: [GLib] Support arrow-gpu
    
    arrow-gpu isn't required. If `arrow-gpu.pc` isn't installed, GPU support is just ignored.
    
    Author: Kouhei Sutou <kou@clear-code.com>
    
    Closes #1313 from kou/glib-gpu and squashes the following commits:
    
    b36d491a [Kouhei Sutou] [GLib] Support arrow-gpu
---
 c_glib/.gitignore                                  |   1 +
 c_glib/Makefile.am                                 |   1 +
 c_glib/arrow-glib/Makefile.am                      |   8 +-
 c_glib/arrow-glib/buffer.h                         |  82 +-
 c_glib/arrow-glib/input-stream.h                   | 136 +--
 c_glib/arrow-glib/meson.build                      |  33 +-
 c_glib/arrow-glib/output-stream.h                  |  47 +-
 c_glib/arrow-glib/readable.cpp                     |   4 +-
 c_glib/arrow-glib/readable.hpp                     |   1 +
 c_glib/arrow-gpu-glib/Makefile.am                  | 109 +++
 .../arrow-gpu-glib.h}                              |  18 +-
 .../arrow-gpu-glib.hpp}                            |  18 +-
 .../arrow-gpu-glib.pc.in}                          |  13 +-
 c_glib/arrow-gpu-glib/cuda.cpp                     | 941 +++++++++++++++++++++
 c_glib/arrow-gpu-glib/cuda.h                       | 181 ++++
 c_glib/arrow-gpu-glib/cuda.hpp                     |  54 ++
 c_glib/arrow-gpu-glib/meson.build                  |  80 ++
 c_glib/configure.ac                                |  26 +-
 c_glib/doc/Makefile.am                             |   2 +-
 c_glib/doc/reference/Makefile.am                   |  11 +
 c_glib/doc/reference/arrow-glib-docs.sgml          |  10 +
 c_glib/doc/reference/meson.build                   |  23 +-
 c_glib/meson.build                                 |   9 +-
 c_glib/test/run-test.rb                            |   6 +
 c_glib/test/run-test.sh                            |  37 +-
 c_glib/test/test-gpu-cuda.rb                       | 144 ++++
 26 files changed, 1683 insertions(+), 312 deletions(-)

diff --git a/c_glib/.gitignore b/c_glib/.gitignore
index 03bb0fe..2719147 100644
--- a/c_glib/.gitignore
+++ b/c_glib/.gitignore
@@ -41,6 +41,7 @@ Makefile.in
 /arrow-glib/enums.h
 /arrow-glib/stamp-*
 /arrow-glib/*.pc
+/arrow-gpu-glib/*.pc
 /example/build
 /example/read-batch
 /example/read-stream
diff --git a/c_glib/Makefile.am b/c_glib/Makefile.am
index 577b749..4cc70e5 100644
--- a/c_glib/Makefile.am
+++ b/c_glib/Makefile.am
@@ -19,6 +19,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 
 SUBDIRS =					\
 	arrow-glib				\
+	arrow-gpu-glib				\
 	doc					\
 	example					\
 	tool
diff --git a/c_glib/arrow-glib/Makefile.am b/c_glib/arrow-glib/Makefile.am
index bf68ec4..5ecb1a6 100644
--- a/c_glib/arrow-glib/Makefile.am
+++ b/c_glib/arrow-glib/Makefile.am
@@ -203,20 +203,18 @@ pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA =				\
 	arrow-glib.pc
 
-# GObject Introspection
+if HAVE_INTROSPECTION
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS =
 INTROSPECTION_SCANNER_ARGS =
 INTROSPECTION_COMPILER_ARGS =
 
-if HAVE_INTROSPECTION
 Arrow-1.0.gir: libarrow-glib.la
 Arrow_1_0_gir_PACKAGES =			\
-	gobject-2.0				\
 	gio-2.0
-Arrow_1_0_gir_EXPORT_PACKAGES = arrow
+Arrow_1_0_gir_EXPORT_PACKAGES =			\
+	arrow-glib
 Arrow_1_0_gir_INCLUDES =			\
-	GObject-2.0				\
 	Gio-2.0
 Arrow_1_0_gir_CFLAGS =				\
 	$(AM_CPPFLAGS)
diff --git a/c_glib/arrow-glib/buffer.h b/c_glib/arrow-glib/buffer.h
index b3f3a2c..300bb4f 100644
--- a/c_glib/arrow-glib/buffer.h
+++ b/c_glib/arrow-glib/buffer.h
@@ -19,44 +19,21 @@
 
 #pragma once
 
-#include <glib-object.h>
+#include <arrow-glib/gobject-type.h>
 
 G_BEGIN_DECLS
 
-#define GARROW_TYPE_BUFFER \
-  (garrow_buffer_get_type())
-#define GARROW_BUFFER(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj), GARROW_TYPE_BUFFER, GArrowBuffer))
-#define GARROW_BUFFER_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass), GARROW_TYPE_BUFFER, GArrowBufferClass))
-#define GARROW_IS_BUFFER(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GARROW_TYPE_BUFFER))
-#define GARROW_IS_BUFFER_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass), GARROW_TYPE_BUFFER))
-#define GARROW_BUFFER_GET_CLASS(obj) \
-  (G_TYPE_INSTANCE_GET_CLASS((obj), GARROW_TYPE_BUFFER, GArrowBufferClass))
-
-typedef struct _GArrowBuffer         GArrowBuffer;
-typedef struct _GArrowBufferClass    GArrowBufferClass;
-
-/**
- * GArrowBuffer:
- *
- * It wraps `arrow::Buffer`.
- */
-struct _GArrowBuffer
-{
-  /*< private >*/
-  GObject parent_instance;
-};
-
+#define GARROW_TYPE_BUFFER (garrow_buffer_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowBuffer,
+                         garrow_buffer,
+                         GARROW,
+                         BUFFER,
+                         GObject)
 struct _GArrowBufferClass
 {
   GObjectClass parent_class;
 };
 
-GType          garrow_buffer_get_type     (void) G_GNUC_CONST;
-
 GArrowBuffer  *garrow_buffer_new          (const guint8 *data,
                                            gint64 size);
 gboolean       garrow_buffer_equal        (GArrowBuffer *buffer,
@@ -80,49 +57,16 @@ GArrowBuffer  *garrow_buffer_slice        (GArrowBuffer *buffer,
                                            gint64 size);
 
 
-#define GARROW_TYPE_MUTABLE_BUFFER              \
-  (garrow_mutable_buffer_get_type())
-#define GARROW_MUTABLE_BUFFER(obj)                              \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),                            \
-                              GARROW_TYPE_MUTABLE_BUFFER,       \
-                              GArrowMutableBuffer))
-#define GARROW_MUTABLE_BUFFER_CLASS(klass)              \
-  (G_TYPE_CHECK_CLASS_CAST((klass),                     \
-                           GARROW_TYPE_MUTABLE_BUFFER,  \
-                           GArrowMutableBufferClass))
-#define GARROW_IS_MUTABLE_BUFFER(obj)                                   \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GARROW_TYPE_MUTABLE_BUFFER))
-#define GARROW_IS_MUTABLE_BUFFER_CLASS(klass)                           \
-  (G_TYPE_CHECK_CLASS_TYPE((klass), GARROW_TYPE_MUTABLE_BUFFER))
-#define GARROW_MUTABLE_BUFFER_GET_CLASS(obj)                    \
-  (G_TYPE_INSTANCE_GET_CLASS((obj),                             \
-                             GARROW_TYPE_MUTABLE_BUFFER,        \
-                             GArrowMutableBufferClass))
-
-typedef struct _GArrowMutableBuffer         GArrowMutableBuffer;
-#ifndef __GTK_DOC_IGNORE__
-typedef struct _GArrowMutableBufferClass    GArrowMutableBufferClass;
-#endif
-
-/**
- * GArrowMutableBuffer:
- *
- * It wraps `arrow::MutableBuffer`.
- */
-struct _GArrowMutableBuffer
-{
-  /*< private >*/
-  GArrowBuffer parent_instance;
-};
-
-#ifndef __GTK_DOC_IGNORE__
+#define GARROW_TYPE_MUTABLE_BUFFER (garrow_mutable_buffer_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowMutableBuffer,
+                         garrow_mutable_buffer,
+                         GARROW,
+                         MUTABLE_BUFFER,
+                         GArrowBuffer)
 struct _GArrowMutableBufferClass
 {
   GArrowBufferClass parent_class;
 };
-#endif
-
-GType garrow_mutable_buffer_get_type(void) G_GNUC_CONST;
 
 GArrowMutableBuffer *garrow_mutable_buffer_new  (guint8 *data,
                                                  gint64 size);
diff --git a/c_glib/arrow-glib/input-stream.h b/c_glib/arrow-glib/input-stream.h
index 12c7ae7..c2068d6 100644
--- a/c_glib/arrow-glib/input-stream.h
+++ b/c_glib/arrow-glib/input-stream.h
@@ -26,98 +26,28 @@
 
 G_BEGIN_DECLS
 
-#define GARROW_TYPE_INPUT_STREAM                \
-  (garrow_input_stream_get_type())
-#define GARROW_INPUT_STREAM(obj)                        \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),                    \
-                              GARROW_TYPE_INPUT_STREAM, \
-                              GArrowInputStream))
-#define GARROW_INPUT_STREAM_CLASS(klass)                \
-  (G_TYPE_CHECK_CLASS_CAST((klass),                     \
-                           GARROW_TYPE_INPUT_STREAM,    \
-                           GArrowInputStreamClass))
-#define GARROW_IS_INPUT_STREAM(obj)                             \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),                            \
-                              GARROW_TYPE_INPUT_STREAM))
-#define GARROW_IS_INPUT_STREAM_CLASS(klass)             \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),                     \
-                           GARROW_TYPE_INPUT_STREAM))
-#define GARROW_INPUT_STREAM_GET_CLASS(obj)              \
-  (G_TYPE_INSTANCE_GET_CLASS((obj),                     \
-                             GARROW_TYPE_INPUT_STREAM,  \
-                             GArrowInputStreamClass))
-
-typedef struct _GArrowInputStream         GArrowInputStream;
-#ifndef __GTK_DOC_IGNORE__
-typedef struct _GArrowInputStreamClass    GArrowInputStreamClass;
-#endif
-
-/**
- * GArrowInputStream:
- *
- * It wraps `arrow::io::InputStream`.
- */
-struct _GArrowInputStream
-{
-  /*< private >*/
-  GObject parent_instance;
-};
-
-#ifndef __GTK_DOC_IGNORE__
+#define GARROW_TYPE_INPUT_STREAM (garrow_input_stream_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowInputStream,
+                         garrow_input_stream,
+                         GARROW,
+                         INPUT_STREAM,
+                         GObject)
 struct _GArrowInputStreamClass
 {
   GObjectClass parent_class;
 };
-#endif
-
-GType garrow_input_stream_get_type(void) G_GNUC_CONST;
-
 
 #define GARROW_TYPE_SEEKABLE_INPUT_STREAM       \
   (garrow_seekable_input_stream_get_type())
-#define GARROW_SEEKABLE_INPUT_STREAM(obj)                               \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),                                    \
-                              GARROW_TYPE_SEEKABLE_INPUT_STREAM,        \
-                              GArrowSeekableInputStream))
-#define GARROW_SEEKABLE_INPUT_STREAM_CLASS(klass)               \
-  (G_TYPE_CHECK_CLASS_CAST((klass),                             \
-                           GARROW_TYPE_SEEKABLE_INPUT_STREAM,   \
-                           GArrowSeekableInputStreamClass))
-#define GARROW_IS_SEEKABLE_INPUT_STREAM(obj)                            \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),                                    \
-                              GARROW_TYPE_SEEKABLE_INPUT_STREAM))
-#define GARROW_IS_SEEKABLE_INPUT_STREAM_CLASS(klass)            \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),                             \
-                           GARROW_TYPE_SEEKABLE_INPUT_STREAM))
-#define GARROW_SEEKABLE_INPUT_STREAM_GET_CLASS(obj)             \
-  (G_TYPE_INSTANCE_GET_CLASS((obj),                             \
-                             GARROW_TYPE_SEEKABLE_INPUT_STREAM, \
-                             GArrowSeekableInputStreamClass))
-
-typedef struct _GArrowSeekableInputStream         GArrowSeekableInputStream;
-#ifndef __GTK_DOC_IGNORE__
-typedef struct _GArrowSeekableInputStreamClass    GArrowSeekableInputStreamClass;
-#endif
-
-/**
- * GArrowSeekableInputStream:
- *
- * It wraps `arrow::io::RandomAccessFile`.
- */
-struct _GArrowSeekableInputStream
-{
-  /*< private >*/
-  GArrowInputStream parent_instance;
-};
-
-#ifndef __GTK_DOC_IGNORE__
+G_DECLARE_DERIVABLE_TYPE(GArrowSeekableInputStream,
+                         garrow_seekable_input_stream,
+                         GARROW,
+                         SEEKABLE_INPUT_STREAM,
+                         GArrowInputStream)
 struct _GArrowSeekableInputStreamClass
 {
   GArrowInputStreamClass parent_class;
 };
-#endif
-
-GType garrow_seekable_input_stream_get_type(void) G_GNUC_CONST;
 
 guint64 garrow_seekable_input_stream_get_size(GArrowSeekableInputStream *input_stream,
                                               GError **error);
@@ -133,49 +63,15 @@ GArrowTensor *garrow_seekable_input_stream_read_tensor(GArrowSeekableInputStream
 
 #define GARROW_TYPE_BUFFER_INPUT_STREAM         \
   (garrow_buffer_input_stream_get_type())
-#define GARROW_BUFFER_INPUT_STREAM(obj)                         \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),                            \
-                              GARROW_TYPE_BUFFER_INPUT_STREAM,  \
-                              GArrowBufferInputStream))
-#define GARROW_BUFFER_INPUT_STREAM_CLASS(klass)                 \
-  (G_TYPE_CHECK_CLASS_CAST((klass),                             \
-                           GARROW_TYPE_BUFFER_INPUT_STREAM,     \
-                           GArrowBufferInputStreamClass))
-#define GARROW_IS_BUFFER_INPUT_STREAM(obj)                      \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),                            \
-                              GARROW_TYPE_BUFFER_INPUT_STREAM))
-#define GARROW_IS_BUFFER_INPUT_STREAM_CLASS(klass)              \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),                             \
-                           GARROW_TYPE_BUFFER_INPUT_STREAM))
-#define GARROW_BUFFER_INPUT_STREAM_GET_CLASS(obj)               \
-  (G_TYPE_INSTANCE_GET_CLASS((obj),                             \
-                             GARROW_TYPE_BUFFER_INPUT_STREAM,   \
-                             GArrowBufferInputStreamClass))
-
-typedef struct _GArrowBufferInputStream         GArrowBufferInputStream;
-#ifndef __GTK_DOC_IGNORE__
-typedef struct _GArrowBufferInputStreamClass    GArrowBufferInputStreamClass;
-#endif
-
-/**
- * GArrowBufferInputStream:
- *
- * It wraps `arrow::io::BufferReader`.
- */
-struct _GArrowBufferInputStream
-{
-  /*< private >*/
-  GArrowSeekableInputStream parent_instance;
-};
-
-#ifndef __GTK_DOC_IGNORE__
+G_DECLARE_DERIVABLE_TYPE(GArrowBufferInputStream,
+                         garrow_buffer_input_stream,
+                         GARROW,
+                         BUFFER_INPUT_STREAM,
+                         GArrowSeekableInputStream)
 struct _GArrowBufferInputStreamClass
 {
   GArrowSeekableInputStreamClass parent_class;
 };
-#endif
-
-GType garrow_buffer_input_stream_get_type(void) G_GNUC_CONST;
 
 GArrowBufferInputStream *garrow_buffer_input_stream_new(GArrowBuffer *buffer);
 
diff --git a/c_glib/arrow-glib/meson.build b/c_glib/arrow-glib/meson.build
index 464a002..aeec417 100644
--- a/c_glib/arrow-glib/meson.build
+++ b/c_glib/arrow-glib/meson.build
@@ -179,22 +179,23 @@ pkgconfig.generate(filebase: meson.project_name(),
                    name: 'Apache Arrow GLib',
                    description: 'C API for Apache Arrow based on GLib',
                    version: version,
-                   requires: ['gobject-2.0', 'arrow'],
+                   requires: ['gio-2.0', 'arrow'],
                    libraries: [libarrow_glib],
                    subdirs: ['arrow-glib'])
 
-gnome.generate_gir(libarrow_glib,
-                   sources: sources + c_headers + enums,
-                   namespace: 'Arrow',
-                   nsversion: api_version,
-                   identifier_prefix: 'GArrow',
-                   symbol_prefix: 'garrow',
-                   export_packages: 'arrow-glib',
-                   includes: [
-                     'GObject-2.0',
-                     'Gio-2.0',
-                   ],
-                   install: true,
-                   extra_args: [
-                     '--warn-all',
-                   ])
+arrow_glib_gir = gnome.generate_gir(libarrow_glib,
+                                    sources: sources + c_headers + enums,
+                                    namespace: 'Arrow',
+                                    nsversion: api_version,
+                                    identifier_prefix: 'GArrow',
+                                    symbol_prefix: 'garrow',
+                                    export_packages: 'arrow-glib',
+                                    includes: [
+                                      'GObject-2.0',
+                                      'Gio-2.0',
+                                    ],
+                                    install: true,
+                                    extra_args: [
+                                      '--warn-all',
+                                    ])
+arrow_glib_gir_dependency = declare_dependency(sources: arrow_glib_gir)
diff --git a/c_glib/arrow-glib/output-stream.h b/c_glib/arrow-glib/output-stream.h
index e42ebcd..195a97a 100644
--- a/c_glib/arrow-glib/output-stream.h
+++ b/c_glib/arrow-glib/output-stream.h
@@ -26,51 +26,16 @@
 
 G_BEGIN_DECLS
 
-#define GARROW_TYPE_OUTPUT_STREAM               \
-  (garrow_output_stream_get_type())
-#define GARROW_OUTPUT_STREAM(obj)                               \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),                            \
-                              GARROW_TYPE_OUTPUT_STREAM,        \
-                              GArrowOutputStream))
-#define GARROW_OUTPUT_STREAM_CLASS(klass)               \
-  (G_TYPE_CHECK_CLASS_CAST((klass),                     \
-                           GARROW_TYPE_OUTPUT_STREAM,   \
-                           GArrowOutputStreamClass))
-#define GARROW_IS_OUTPUT_STREAM(obj)                            \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),                            \
-                              GARROW_TYPE_OUTPUT_STREAM))
-#define GARROW_IS_OUTPUT_STREAM_CLASS(klass)            \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),                     \
-                           GARROW_TYPE_OUTPUT_STREAM))
-#define GARROW_OUTPUT_STREAM_GET_CLASS(obj)             \
-  (G_TYPE_INSTANCE_GET_CLASS((obj),                     \
-                             GARROW_TYPE_OUTPUT_STREAM, \
-                             GArrowOutputStreamClass))
-
-typedef struct _GArrowOutputStream          GArrowOutputStream;
-#ifndef __GTK_DOC_IGNORE__
-typedef struct _GArrowOutputStreamClass     GArrowOutputStreamClass;
-#endif
-
-/**
- * GArrowOutputStream:
- *
- * It wraps `arrow::io::OutputStream`.
- */
-struct _GArrowOutputStream
-{
-  /*< private >*/
-  GObject parent_instance;
-};
-
-#ifndef __GTK_DOC_IGNORE__
+#define GARROW_TYPE_OUTPUT_STREAM (garrow_output_stream_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowOutputStream,
+                         garrow_output_stream,
+                         GARROW,
+                         OUTPUT_STREAM,
+                         GObject)
 struct _GArrowOutputStreamClass
 {
   GObjectClass parent_class;
 };
-#endif
-
-GType garrow_output_stream_get_type(void) G_GNUC_CONST;
 
 gint64 garrow_output_stream_write_tensor(GArrowOutputStream *stream,
                                          GArrowTensor *tensor,
diff --git a/c_glib/arrow-glib/readable.cpp b/c_glib/arrow-glib/readable.cpp
index 6a9023e..33f98d9 100644
--- a/c_glib/arrow-glib/readable.cpp
+++ b/c_glib/arrow-glib/readable.cpp
@@ -45,6 +45,7 @@ G_DEFINE_INTERFACE(GArrowReadable,
 static void
 garrow_readable_default_init (GArrowReadableInterface *iface)
 {
+  iface->new_raw = garrow_buffer_new_raw;
 }
 
 /**
@@ -66,7 +67,8 @@ garrow_readable_read(GArrowReadable *readable,
   std::shared_ptr<arrow::Buffer> arrow_buffer;
   auto status = arrow_readable->Read(n_bytes, &arrow_buffer);
   if (garrow_error_check(error, status, "[io][readable][read]")) {
-    return garrow_buffer_new_raw(&arrow_buffer);
+    auto *iface = GARROW_READABLE_GET_IFACE(readable);
+    return iface->new_raw(&arrow_buffer);
   } else {
     return NULL;
   }
diff --git a/c_glib/arrow-glib/readable.hpp b/c_glib/arrow-glib/readable.hpp
index c241c77..ce77701 100644
--- a/c_glib/arrow-glib/readable.hpp
+++ b/c_glib/arrow-glib/readable.hpp
@@ -32,6 +32,7 @@ struct _GArrowReadableInterface
 {
   GTypeInterface parent_iface;
 
+  GArrowBuffer *(*new_raw)(std::shared_ptr<arrow::Buffer> *arrow_buffer);
   std::shared_ptr<arrow::io::Readable> (*get_raw)(GArrowReadable *file);
 };
 
diff --git a/c_glib/arrow-gpu-glib/Makefile.am b/c_glib/arrow-gpu-glib/Makefile.am
new file mode 100644
index 0000000..ec96159
--- /dev/null
+++ b/c_glib/arrow-gpu-glib/Makefile.am
@@ -0,0 +1,109 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+CLEANFILES =
+
+EXTRA_DIST =					\
+	meson.build
+
+AM_CPPFLAGS =					\
+	-I$(top_builddir)			\
+	-I$(top_srcdir)
+
+if HAVE_ARROW_GPU
+lib_LTLIBRARIES =				\
+	libarrow-gpu-glib.la
+
+libarrow_gpu_glib_la_CXXFLAGS =			\
+	$(GLIB_CFLAGS)				\
+	$(ARROW_CFLAGS)				\
+	$(ARROW_GPU_CFLAGS)			\
+	$(GARROW_CXXFLAGS)
+
+libarrow_gpu_glib_la_LIBADD =			\
+	$(GLIB_LIBS)				\
+	$(ARROW_LIBS)				\
+	$(ARROW_GPU_LIBS)			\
+	../arrow-glib/libarrow-glib.la
+
+libarrow_gpu_glib_la_headers =			\
+	arrow-gpu-glib.h			\
+	cuda.h
+
+libarrow_gpu_glib_la_sources =			\
+	cuda.cpp				\
+	$(libarrow_gpu_glib_la_headers)
+
+libarrow_gpu_glib_la_cpp_headers =		\
+	arrow-gpu-glib.hpp			\
+	cuda.hpp
+
+libarrow_gpu_glib_la_SOURCES =			\
+	$(libarrow_gpu_glib_la_sources)		\
+	$(libarrow_gpu_glib_la_cpp_headers)
+
+arrow_gpu_glib_includedir =			\
+	$(includedir)/arrow-gpu-glib
+arrow_gpu_glib_include_HEADERS =		\
+	$(libarrow_gpu_glib_la_headers)		\
+	$(libarrow_gpu_glib_la_cpp_headers)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =				\
+	arrow-gpu-glib.pc
+
+if HAVE_INTROSPECTION
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS =
+INTROSPECTION_SCANNER_ENV =			\
+	PKG_CONFIG_PATH=${abs_builddir}/../arrow-glib:$${PKG_CONFIG_PATH}
+INTROSPECTION_COMPILER_ARGS =			\
+	--includedir=$(abs_builddir)/../arrow-glib
+
+ArrowGPU-1.0.gir: libarrow-gpu-glib.la
+ArrowGPU_1_0_gir_PACKAGES =			\
+	arrow-glib
+ArrowGPU_1_0_gir_EXPORT_PACKAGES =		\
+	arrow-gpu-glib
+ArrowGPU_1_0_gir_INCLUDES =			\
+	Arrow-1.0
+ArrowGPU_1_0_gir_CFLAGS =			\
+	$(AM_CPPFLAGS)
+ArrowGPU_1_0_gir_LIBS =					\
+	$(abs_builddir)/../arrow-glib/libarrow-glib.la	\
+	libarrow-gpu-glib.la
+ArrowGPU_1_0_gir_FILES =			\
+	$(libarrow_gpu_glib_la_sources)
+ArrowGPU_1_0_gir_SCANNERFLAGS =					\
+	--warn-all						\
+	--add-include-path=$(abs_builddir)/../arrow-glib	\
+	--identifier-prefix=GArrowGPU				\
+	--symbol-prefix=garrow_gpu
+INTROSPECTION_GIRS += ArrowGPU-1.0.gir
+
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES +=					\
+	$(gir_DATA)				\
+	$(typelib_DATA)
+endif
+endif
diff --git a/c_glib/arrow-glib/readable.hpp b/c_glib/arrow-gpu-glib/arrow-gpu-glib.h
similarity index 68%
copy from c_glib/arrow-glib/readable.hpp
copy to c_glib/arrow-gpu-glib/arrow-gpu-glib.h
index c241c77..1538c9a 100644
--- a/c_glib/arrow-glib/readable.hpp
+++ b/c_glib/arrow-gpu-glib/arrow-gpu-glib.h
@@ -19,20 +19,6 @@
 
 #pragma once
 
-#include <arrow/io/interfaces.h>
+#include <arrow-glib/arrow-glib.h>
 
-#include <arrow-glib/readable.h>
-
-/**
- * GArrowReadableInterface:
- *
- * It wraps `arrow::io::Readable`.
- */
-struct _GArrowReadableInterface
-{
-  GTypeInterface parent_iface;
-
-  std::shared_ptr<arrow::io::Readable> (*get_raw)(GArrowReadable *file);
-};
-
-std::shared_ptr<arrow::io::Readable> garrow_readable_get_raw(GArrowReadable *readable);
+#include <arrow-gpu-glib/cuda.h>
diff --git a/c_glib/arrow-glib/readable.hpp b/c_glib/arrow-gpu-glib/arrow-gpu-glib.hpp
similarity index 68%
copy from c_glib/arrow-glib/readable.hpp
copy to c_glib/arrow-gpu-glib/arrow-gpu-glib.hpp
index c241c77..92017d8 100644
--- a/c_glib/arrow-glib/readable.hpp
+++ b/c_glib/arrow-gpu-glib/arrow-gpu-glib.hpp
@@ -19,20 +19,6 @@
 
 #pragma once
 
-#include <arrow/io/interfaces.h>
+#include <arrow-glib/arrow-glib.hpp>
 
-#include <arrow-glib/readable.h>
-
-/**
- * GArrowReadableInterface:
- *
- * It wraps `arrow::io::Readable`.
- */
-struct _GArrowReadableInterface
-{
-  GTypeInterface parent_iface;
-
-  std::shared_ptr<arrow::io::Readable> (*get_raw)(GArrowReadable *file);
-};
-
-std::shared_ptr<arrow::io::Readable> garrow_readable_get_raw(GArrowReadable *readable);
+#include <arrow-gpu-glib/cuda.hpp>
diff --git a/c_glib/doc/Makefile.am b/c_glib/arrow-gpu-glib/arrow-gpu-glib.pc.in
similarity index 74%
copy from c_glib/doc/Makefile.am
copy to c_glib/arrow-gpu-glib/arrow-gpu-glib.pc.in
index 85c1d51..38a6bae 100644
--- a/c_glib/doc/Makefile.am
+++ b/c_glib/arrow-gpu-glib/arrow-gpu-glib.pc.in
@@ -15,5 +15,14 @@
 # specific language governing permissions and limitations
 # under the License.
 
-SUBDIRS =                                       \
-        reference
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Apache Arrow GPU GLib
+Description: C API for Apache Arrow GPU based on GLib
+Version: @VERSION@
+Libs: -L${libdir} -larrow-gpu-glib
+Cflags: -I${includedir}
+Requires: arrow-glib
diff --git a/c_glib/arrow-gpu-glib/cuda.cpp b/c_glib/arrow-gpu-glib/cuda.cpp
new file mode 100644
index 0000000..c2a9af5
--- /dev/null
+++ b/c_glib/arrow-gpu-glib/cuda.cpp
@@ -0,0 +1,941 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <arrow-glib/buffer.hpp>
+#include <arrow-glib/error.hpp>
+#include <arrow-glib/input-stream.hpp>
+#include <arrow-glib/output-stream.hpp>
+#include <arrow-glib/readable.hpp>
+#include <arrow-glib/record-batch.hpp>
+#include <arrow-glib/schema.hpp>
+
+#include <arrow-gpu-glib/cuda.hpp>
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION: cuda
+ * @section_id: cuda-classes
+ * @title: CUDA related classes
+ * @include: arrow-gpu-glib/arrow-gpu-glib.h
+ *
+ * The following classes provide CUDA support for Apache Arrow data.
+ *
+ * #GArrowGPUCUDADeviceManager is the starting point. You need at
+ * least one #GArrowGPUCUDAContext to process Apache Arrow data on
+ * NVIDIA GPU.
+ *
+ * #GArrowGPUCUDAContext is a class to keep context for one GPU. You
+ * need to create #GArrowGPUCUDAContext for each GPU that you want to
+ * use. You can create #GArrowGPUCUDAContext by
+ * garrow_gpu_cuda_device_manager_get_context().
+ *
+ * #GArrowGPUCUDABuffer is a class for data on GPU. You can copy data
+ * on GPU to/from CPU by garrow_gpu_cuda_buffer_copy_to_host() and
+ * garrow_gpu_cuda_buffer_copy_from_host(). You can share data on GPU
+ * with other processes by garrow_gpu_cuda_buffer_export() and
+ * garrow_gpu_cuda_buffer_new_ipc().
+ *
+ * #GArrowGPUCUDAHostBuffer is a class for data on CPU that is
+ * directly accessible from GPU.
+ *
+ * #GArrowGPUCUDAIPCMemoryHandle is a class to share data on GPU with
+ * other processes. You can export your data on GPU to other processes
+ * by garrow_gpu_cuda_buffer_export() and
+ * garrow_gpu_cuda_ipc_memory_handle_new(). You can import other
+ * process data on GPU by garrow_gpu_cuda_ipc_memory_handle_new() and
+ * garrow_gpu_cuda_buffer_new_ipc().
+ *
+ * #GArrowGPUCUDABufferInputStream is a class to read data in
+ * #GArrowGPUCUDABuffer.
+ *
+ * #GArrowGPUCUDABufferOutputStream is a class to write data into
+ * #GArrowGPUCUDABuffer.
+ */
+
+G_DEFINE_TYPE(GArrowGPUCUDADeviceManager,
+              garrow_gpu_cuda_device_manager,
+              G_TYPE_OBJECT)
+
+static void
+garrow_gpu_cuda_device_manager_init(GArrowGPUCUDADeviceManager *object)
+{
+}
+
+static void
+garrow_gpu_cuda_device_manager_class_init(GArrowGPUCUDADeviceManagerClass *klass)
+{
+}
+
+/**
+ * garrow_gpu_cuda_device_manager_new:
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GArrowGPUCUDADeviceManager on success,
+ *   %NULL on error.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDADeviceManager *
+garrow_gpu_cuda_device_manager_new(GError **error)
+{
+  arrow::gpu::CudaDeviceManager *manager;
+  auto status = arrow::gpu::CudaDeviceManager::GetInstance(&manager);
+  if (garrow_error_check(error, status, "[gpu][cuda][device-manager][new]")) {
+    auto manager = g_object_new(GARROW_GPU_TYPE_CUDA_DEVICE_MANAGER,
+                                NULL);
+    return GARROW_GPU_CUDA_DEVICE_MANAGER(manager);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_device_manager_get_context:
+ * @manager: A #GArrowGPUCUDADeviceManager.
+ * @gpu_number: A GPU device number for the target context.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowGPUCUDAContext on
+ *   success, %NULL on error. Contexts for the same GPU device number
+ *   share the same data internally.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDAContext *
+garrow_gpu_cuda_device_manager_get_context(GArrowGPUCUDADeviceManager *manager,
+                                           gint gpu_number,
+                                           GError **error)
+{
+  arrow::gpu::CudaDeviceManager *arrow_manager;
+  arrow::gpu::CudaDeviceManager::GetInstance(&arrow_manager);
+  std::shared_ptr<arrow::gpu::CudaContext> context;
+  auto status = arrow_manager->GetContext(gpu_number, &context);
+  if (garrow_error_check(error, status,
+                         "[gpu][cuda][device-manager][get-context]]")) {
+    return garrow_gpu_cuda_context_new_raw(&context);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_device_manager_get_n_devices:
+ * @manager: A #GArrowGPUCUDADeviceManager.
+ *
+ * Returns: The number of GPU devices.
+ *
+ * Since: 0.8.0
+ */
+gsize
+garrow_gpu_cuda_device_manager_get_n_devices(GArrowGPUCUDADeviceManager *manager)
+{
+  arrow::gpu::CudaDeviceManager *arrow_manager;
+  arrow::gpu::CudaDeviceManager::GetInstance(&arrow_manager);
+  return arrow_manager->num_devices();
+}
+
+
+typedef struct GArrowGPUCUDAContextPrivate_ {
+  std::shared_ptr<arrow::gpu::CudaContext> context;
+} GArrowGPUCUDAContextPrivate;
+
+enum {
+  PROP_CONTEXT = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowGPUCUDAContext,
+                           garrow_gpu_cuda_context,
+                           G_TYPE_OBJECT)
+
+#define GARROW_GPU_CUDA_CONTEXT_GET_PRIVATE(object)     \
+  static_cast<GArrowGPUCUDAContextPrivate *>(           \
+    garrow_gpu_cuda_context_get_instance_private(       \
+      GARROW_GPU_CUDA_CONTEXT(object)))
+
+static void
+garrow_gpu_cuda_context_finalize(GObject *object)
+{
+  auto priv = GARROW_GPU_CUDA_CONTEXT_GET_PRIVATE(object);
+
+  priv->context = nullptr;
+
+  G_OBJECT_CLASS(garrow_gpu_cuda_context_parent_class)->finalize(object);
+}
+
+static void
+garrow_gpu_cuda_context_set_property(GObject *object,
+                                     guint prop_id,
+                                     const GValue *value,
+                                     GParamSpec *pspec)
+{
+  auto priv = GARROW_GPU_CUDA_CONTEXT_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_CONTEXT:
+    priv->context =
+      *static_cast<std::shared_ptr<arrow::gpu::CudaContext> *>(g_value_get_pointer(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_gpu_cuda_context_get_property(GObject *object,
+                                     guint prop_id,
+                                     GValue *value,
+                                     GParamSpec *pspec)
+{
+  switch (prop_id) {
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_gpu_cuda_context_init(GArrowGPUCUDAContext *object)
+{
+}
+
+static void
+garrow_gpu_cuda_context_class_init(GArrowGPUCUDAContextClass *klass)
+{
+  GParamSpec *spec;
+
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize     = garrow_gpu_cuda_context_finalize;
+  gobject_class->set_property = garrow_gpu_cuda_context_set_property;
+  gobject_class->get_property = garrow_gpu_cuda_context_get_property;
+
+  /**
+   * GArrowGPUCUDAContext:context:
+   *
+   * Since: 0.8.0
+   */
+  spec = g_param_spec_pointer("context",
+                              "Context",
+                              "The raw std::shared_ptr<arrow::gpu::CudaContext> *",
+                              static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                                                       G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_CONTEXT, spec);
+}
+
+/**
+ * garrow_gpu_cuda_context_get_allocated_size:
+ * @context: A #GArrowGPUCUDAContext.
+ *
+ * Returns: The allocated memory by this context in bytes.
+ *
+ * Since: 0.8.0
+ */
+gint64
+garrow_gpu_cuda_context_get_allocated_size(GArrowGPUCUDAContext *context)
+{
+  auto arrow_context = garrow_gpu_cuda_context_get_raw(context);
+  return arrow_context->bytes_allocated();
+}
+
+
+G_DEFINE_TYPE(GArrowGPUCUDABuffer,
+              garrow_gpu_cuda_buffer,
+              GARROW_TYPE_BUFFER)
+
+static void
+garrow_gpu_cuda_buffer_init(GArrowGPUCUDABuffer *object)
+{
+}
+
+static void
+garrow_gpu_cuda_buffer_class_init(GArrowGPUCUDABufferClass *klass)
+{
+}
+
+/**
+ * garrow_gpu_cuda_buffer_new:
+ * @context: A #GArrowGPUCUDAContext.
+ * @size: The number of bytes to be allocated on GPU device for this context.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowGPUCUDABuffer on
+ *   success, %NULL on error.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new(GArrowGPUCUDAContext *context,
+                           gint64 size,
+                           GError **error)
+{
+  auto arrow_context = garrow_gpu_cuda_context_get_raw(context);
+  std::shared_ptr<arrow::gpu::CudaBuffer> arrow_buffer;
+  auto status = arrow_context->Allocate(size, &arrow_buffer);
+  if (garrow_error_check(error, status, "[gpu][cuda][buffer][new]")) {
+    return garrow_gpu_cuda_buffer_new_raw(&arrow_buffer);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_buffer_new_ipc:
+ * @context: A #GArrowGPUCUDAContext.
+ * @handle: A #GArrowGPUCUDAIPCMemoryHandle to be communicated.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowGPUCUDABuffer on
+ *   success, %NULL on error. The buffer has data from the IPC target.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new_ipc(GArrowGPUCUDAContext *context,
+                               GArrowGPUCUDAIPCMemoryHandle *handle,
+                               GError **error)
+{
+  auto arrow_context = garrow_gpu_cuda_context_get_raw(context);
+  auto arrow_handle = garrow_gpu_cuda_ipc_memory_handle_get_raw(handle);
+  std::shared_ptr<arrow::gpu::CudaBuffer> arrow_buffer;
+  auto status = arrow_context->OpenIpcBuffer(*arrow_handle, &arrow_buffer);
+  if (garrow_error_check(error, status,
+                         "[gpu][cuda][buffer][new-ipc]")) {
+    return garrow_gpu_cuda_buffer_new_raw(&arrow_buffer);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_buffer_new_record_batch:
+ * @context: A #GArrowGPUCUDAContext.
+ * @record_batch: A #GArrowRecordBatch to be serialized.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowGPUCUDABuffer on
+ *   success, %NULL on error. The buffer has serialized record batch
+ *   data.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new_record_batch(GArrowGPUCUDAContext *context,
+                                        GArrowRecordBatch *record_batch,
+                                        GError **error)
+{
+  auto arrow_context = garrow_gpu_cuda_context_get_raw(context);
+  auto arrow_record_batch = garrow_record_batch_get_raw(record_batch);
+  std::shared_ptr<arrow::gpu::CudaBuffer> arrow_buffer;
+  auto status = arrow::gpu::SerializeRecordBatch(*arrow_record_batch,
+                                                 arrow_context.get(),
+                                                 &arrow_buffer);
+  if (garrow_error_check(error, status,
+                         "[gpu][cuda][buffer][new-record-batch]")) {
+    return garrow_gpu_cuda_buffer_new_raw(&arrow_buffer);
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_buffer_copy_to_host:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ * @position: The offset of memory on GPU device to be copied.
+ * @size: The size of memory on GPU device to be copied in bytes.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A #GBytes that have copied memory on CPU
+ *   host on success, %NULL on error.
+ *
+ * Since: 0.8.0
+ */
+GBytes *
+garrow_gpu_cuda_buffer_copy_to_host(GArrowGPUCUDABuffer *buffer,
+                                    gint64 position,
+                                    gint64 size,
+                                    GError **error)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  auto data = static_cast<uint8_t *>(g_malloc(size));
+  auto status = arrow_buffer->CopyToHost(position, size, data);
+  if (garrow_error_check(error, status, "[gpu][cuda][buffer][copy-to-host]")) {
+    return g_bytes_new_take(data, size);
+  } else {
+    g_free(data);
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_buffer_copy_from_host:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ * @data: (array length=size): Data on CPU host to be copied.
+ * @size: The size of data on CPU host to be copied in bytes.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_gpu_cuda_buffer_copy_from_host(GArrowGPUCUDABuffer *buffer,
+                                      const guint8 *data,
+                                      gint64 size,
+                                      GError **error)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  auto status = arrow_buffer->CopyFromHost(0, data, size);
+  return garrow_error_check(error,
+                            status,
+                            "[gpu][cuda][buffer][copy-from-host]");
+}
+
+/**
+ * garrow_gpu_cuda_buffer_export:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created
+ *   #GArrowGPUCUDAIPCMemoryHandle to handle the exported buffer on
+ *   success, %NULL on error
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDAIPCMemoryHandle *
+garrow_gpu_cuda_buffer_export(GArrowGPUCUDABuffer *buffer, GError **error)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  std::unique_ptr<arrow::gpu::CudaIpcMemHandle> arrow_handle;
+  auto status = arrow_buffer->ExportForIpc(&arrow_handle);
+  if (garrow_error_check(error, status, "[gpu][cuda][buffer][export-for-ipc]")) {
+    return garrow_gpu_cuda_ipc_memory_handle_new_raw(arrow_handle.release());
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_buffer_get_context:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ *
+ * Returns: (transfer full): A newly created #GArrowGPUCUDAContext for the
+ *   buffer. Contexts for the same buffer share the same data internally.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDAContext *
+garrow_gpu_cuda_buffer_get_context(GArrowGPUCUDABuffer *buffer)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  auto arrow_context = arrow_buffer->context();
+  return garrow_gpu_cuda_context_new_raw(&arrow_context);
+}
+
+/**
+ * garrow_gpu_cuda_buffer_read_record_batch:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ * @schema: A #GArrowSchema for record batch.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowRecordBatch on
+ *   success, %NULL on error. The record batch data is located on GPU.
+ *
+ * Since: 0.8.0
+ */
+GArrowRecordBatch *
+garrow_gpu_cuda_buffer_read_record_batch(GArrowGPUCUDABuffer *buffer,
+                                         GArrowSchema *schema,
+                                         GError **error)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  auto arrow_schema = garrow_schema_get_raw(schema);
+  auto pool = arrow::default_memory_pool();
+  std::shared_ptr<arrow::RecordBatch> arrow_record_batch;
+  auto status = arrow::gpu::ReadRecordBatch(arrow_schema,
+                                            arrow_buffer,
+                                            pool,
+                                            &arrow_record_batch);
+  if (garrow_error_check(error, status,
+                         "[gpu][cuda][buffer][read-record-batch]")) {
+    return garrow_record_batch_new_raw(&arrow_record_batch);
+  } else {
+    return NULL;
+  }
+}
+
+
+G_DEFINE_TYPE(GArrowGPUCUDAHostBuffer,
+              garrow_gpu_cuda_host_buffer,
+              GARROW_TYPE_MUTABLE_BUFFER)
+
+static void
+garrow_gpu_cuda_host_buffer_init(GArrowGPUCUDAHostBuffer *object)
+{
+}
+
+static void
+garrow_gpu_cuda_host_buffer_class_init(GArrowGPUCUDAHostBufferClass *klass)
+{
+}
+
+/**
+ * garrow_gpu_cuda_host_buffer_new:
+ * @size: The number of bytes to be allocated on CPU host.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GArrowGPUCUDAHostBuffer on success,
+ *   %NULL on error. The allocated memory is accessible from GPU
+ *   device for the @context.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDAHostBuffer *
+garrow_gpu_cuda_host_buffer_new(gint64 size, GError **error)
+{
+  arrow::gpu::CudaDeviceManager *manager;
+  auto status = arrow::gpu::CudaDeviceManager::GetInstance(&manager);
+  std::shared_ptr<arrow::gpu::CudaHostBuffer> arrow_buffer;
+  status = manager->AllocateHost(size, &arrow_buffer);
+  if (garrow_error_check(error, status, "[gpu][cuda][host-buffer][new]")) {
+    return garrow_gpu_cuda_host_buffer_new_raw(&arrow_buffer);
+  } else {
+    return NULL;
+  }
+}
+
+
+typedef struct GArrowGPUCUDAIPCMemoryHandlePrivate_ {
+  arrow::gpu::CudaIpcMemHandle *ipc_memory_handle;
+} GArrowGPUCUDAIPCMemoryHandlePrivate;
+
+enum {
+  PROP_IPC_MEMORY_HANDLE = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowGPUCUDAIPCMemoryHandle,
+                           garrow_gpu_cuda_ipc_memory_handle,
+                           G_TYPE_OBJECT)
+
+#define GARROW_GPU_CUDA_IPC_MEMORY_HANDLE_GET_PRIVATE(object)   \
+  static_cast<GArrowGPUCUDAIPCMemoryHandlePrivate *>(           \
+    garrow_gpu_cuda_ipc_memory_handle_get_instance_private(     \
+      GARROW_GPU_CUDA_IPC_MEMORY_HANDLE(object)))
+
+static void
+garrow_gpu_cuda_ipc_memory_handle_finalize(GObject *object)
+{
+  auto priv = GARROW_GPU_CUDA_IPC_MEMORY_HANDLE_GET_PRIVATE(object);
+
+  delete priv->ipc_memory_handle;
+
+  G_OBJECT_CLASS(garrow_gpu_cuda_ipc_memory_handle_parent_class)->finalize(object);
+}
+
+static void
+garrow_gpu_cuda_ipc_memory_handle_set_property(GObject *object,
+                                               guint prop_id,
+                                               const GValue *value,
+                                               GParamSpec *pspec)
+{
+  auto priv = GARROW_GPU_CUDA_IPC_MEMORY_HANDLE_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_IPC_MEMORY_HANDLE:
+    priv->ipc_memory_handle =
+      static_cast<arrow::gpu::CudaIpcMemHandle *>(g_value_get_pointer(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_gpu_cuda_ipc_memory_handle_get_property(GObject *object,
+                                               guint prop_id,
+                                               GValue *value,
+                                               GParamSpec *pspec)
+{
+  switch (prop_id) {
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_gpu_cuda_ipc_memory_handle_init(GArrowGPUCUDAIPCMemoryHandle *object)
+{
+}
+
+static void
+garrow_gpu_cuda_ipc_memory_handle_class_init(GArrowGPUCUDAIPCMemoryHandleClass *klass)
+{
+  GParamSpec *spec;
+
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize     = garrow_gpu_cuda_ipc_memory_handle_finalize;
+  gobject_class->set_property = garrow_gpu_cuda_ipc_memory_handle_set_property;
+  gobject_class->get_property = garrow_gpu_cuda_ipc_memory_handle_get_property;
+
+  /**
+   * GArrowGPUCUDAIPCMemoryHandle:ipc-memory-handle:
+   *
+   * Since: 0.8.0
+   */
+  spec = g_param_spec_pointer("ipc-memory-handle",
+                              "IPC Memory Handle",
+                              "The raw arrow::gpu::CudaIpcMemHandle *",
+                              static_cast<GParamFlags>(G_PARAM_WRITABLE |
+                                                       G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_IPC_MEMORY_HANDLE, spec);
+}
+
+/**
+ * garrow_gpu_cuda_ipc_memory_handle_new:
+ * @data: (array length=size): A serialized #GArrowGPUCUDAIPCMemoryHandle.
+ * @size: The size of data.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowGPUCUDAIPCMemoryHandle
+ *   on success, %NULL on error.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDAIPCMemoryHandle *
+garrow_gpu_cuda_ipc_memory_handle_new(const guint8 *data,
+                                      gsize size,
+                                      GError **error)
+{
+  std::unique_ptr<arrow::gpu::CudaIpcMemHandle> arrow_handle;
+  auto status = arrow::gpu::CudaIpcMemHandle::FromBuffer(data, &arrow_handle);
+  if (garrow_error_check(error, status,
+                         "[gpu][cuda][ipc-memory-handle][new]")) {
+    return garrow_gpu_cuda_ipc_memory_handle_new_raw(arrow_handle.release());
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * garrow_gpu_cuda_ipc_memory_handle_serialize:
+ * @handle: A #GArrowGPUCUDAIPCMemoryHandle.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (transfer full): A newly created #GArrowBuffer on success,
+ *   %NULL on error. The buffer has serialized @handle. The serialized
+ *   @handle can be deserialized by garrow_gpu_cuda_ipc_memory_handle_new()
+ *   in other process.
+ *
+ * Since: 0.8.0
+ */
+GArrowBuffer *
+garrow_gpu_cuda_ipc_memory_handle_serialize(GArrowGPUCUDAIPCMemoryHandle *handle,
+                                            GError **error)
+{
+  auto arrow_handle = garrow_gpu_cuda_ipc_memory_handle_get_raw(handle);
+  std::shared_ptr<arrow::Buffer> arrow_buffer;
+  auto status = arrow_handle->Serialize(arrow::default_memory_pool(),
+                                        &arrow_buffer);
+  if (garrow_error_check(error, status,
+                         "[gpu][cuda][ipc-memory-handle][serialize]")) {
+    return garrow_buffer_new_raw(&arrow_buffer);
+  } else {
+    return NULL;
+  }
+}
+
+GArrowBuffer *
+garrow_gpu_cuda_buffer_input_stream_new_raw_readable_interface(std::shared_ptr<arrow::Buffer> *arrow_buffer)
+{
+  auto buffer = GARROW_BUFFER(g_object_new(GARROW_GPU_TYPE_CUDA_BUFFER,
+                                           "buffer", arrow_buffer,
+                                           NULL));
+  return buffer;
+}
+
+static std::shared_ptr<arrow::io::Readable>
+garrow_gpu_cuda_buffer_input_stream_get_raw_readable_interface(GArrowReadable *readable)
+{
+  auto input_stream = GARROW_INPUT_STREAM(readable);
+  auto arrow_input_stream = garrow_input_stream_get_raw(input_stream);
+  return arrow_input_stream;
+}
+
+static void
+garrow_gpu_cuda_buffer_input_stream_readable_interface_init(GArrowReadableInterface *iface)
+{
+  iface->new_raw =
+    garrow_gpu_cuda_buffer_input_stream_new_raw_readable_interface;
+  iface->get_raw =
+    garrow_gpu_cuda_buffer_input_stream_get_raw_readable_interface;
+}
+
+G_DEFINE_TYPE_WITH_CODE(
+  GArrowGPUCUDABufferInputStream,
+  garrow_gpu_cuda_buffer_input_stream,
+  GARROW_TYPE_BUFFER_INPUT_STREAM,
+  G_IMPLEMENT_INTERFACE(
+    GARROW_TYPE_READABLE,
+    garrow_gpu_cuda_buffer_input_stream_readable_interface_init))
+
+static void
+garrow_gpu_cuda_buffer_input_stream_init(GArrowGPUCUDABufferInputStream *object)
+{
+}
+
+static void
+garrow_gpu_cuda_buffer_input_stream_class_init(GArrowGPUCUDABufferInputStreamClass *klass)
+{
+}
+
+/**
+ * garrow_gpu_cuda_buffer_input_stream_new:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ *
+ * Returns: (transfer full): A newly created
+ *   #GArrowGPUCUDABufferInputStream.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDABufferInputStream *
+garrow_gpu_cuda_buffer_input_stream_new(GArrowGPUCUDABuffer *buffer)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  auto arrow_reader =
+    std::make_shared<arrow::gpu::CudaBufferReader>(arrow_buffer);
+  return garrow_gpu_cuda_buffer_input_stream_new_raw(&arrow_reader);
+}
+
+
+G_DEFINE_TYPE(GArrowGPUCUDABufferOutputStream,
+              garrow_gpu_cuda_buffer_output_stream,
+              GARROW_TYPE_OUTPUT_STREAM)
+
+static void
+garrow_gpu_cuda_buffer_output_stream_init(GArrowGPUCUDABufferOutputStream *object)
+{
+}
+
+static void
+garrow_gpu_cuda_buffer_output_stream_class_init(GArrowGPUCUDABufferOutputStreamClass *klass)
+{
+}
+
+/**
+ * garrow_gpu_cuda_buffer_output_stream_new:
+ * @buffer: A #GArrowGPUCUDABuffer.
+ *
+ * Returns: (transfer full): A newly created
+ *   #GArrowGPUCUDABufferOutputStream.
+ *
+ * Since: 0.8.0
+ */
+GArrowGPUCUDABufferOutputStream *
+garrow_gpu_cuda_buffer_output_stream_new(GArrowGPUCUDABuffer *buffer)
+{
+  auto arrow_buffer = garrow_gpu_cuda_buffer_get_raw(buffer);
+  auto arrow_writer =
+    std::make_shared<arrow::gpu::CudaBufferWriter>(arrow_buffer);
+  return garrow_gpu_cuda_buffer_output_stream_new_raw(&arrow_writer);
+}
+
+/**
+ * garrow_gpu_cuda_buffer_output_stream_set_buffer_size:
+ * @stream: A #GArrowGPUCUDABufferOutputStream.
+ * @size: A size of CPU buffer in bytes.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: %TRUE on success, %FALSE if there was an error.
+ *
+ * Sets CPU buffer size. to limit `cudaMemcpy()` calls. If CPU buffer
+ * size is `0`, buffering is disabled.
+ *
+ * The default is `0`.
+ *
+ * Since: 0.8.0
+ */
+gboolean
+garrow_gpu_cuda_buffer_output_stream_set_buffer_size(GArrowGPUCUDABufferOutputStream *stream,
+                                                     gint64 size,
+                                                     GError **error)
+{
+  auto arrow_stream = garrow_gpu_cuda_buffer_output_stream_get_raw(stream);
+  auto status = arrow_stream->SetBufferSize(size);
+  return garrow_error_check(error,
+                            status,
+                            "[gpu][cuda][buffer-output-stream][set-buffer-size]");
+}
+
+/**
+ * garrow_gpu_cuda_buffer_output_stream_get_buffer_size:
+ * @stream: A #GArrowGPUCUDABufferOutputStream.
+ *
+ * Returns: The CPU buffer size in bytes.
+ *
+ * See garrow_gpu_cuda_buffer_output_stream_set_buffer_size() for CPU
+ * buffer size details.
+ *
+ * Since: 0.8.0
+ */
+gint64
+garrow_gpu_cuda_buffer_output_stream_get_buffer_size(GArrowGPUCUDABufferOutputStream *stream)
+{
+  auto arrow_stream = garrow_gpu_cuda_buffer_output_stream_get_raw(stream);
+  return arrow_stream->buffer_size();
+}
+
+/**
+ * garrow_gpu_cuda_buffer_output_stream_get_buffered_size:
+ * @stream: A #GArrowGPUCUDABufferOutputStream.
+ *
+ * Returns: The size of buffered data in bytes.
+ *
+ * Since: 0.8.0
+ */
+gint64
+garrow_gpu_cuda_buffer_output_stream_get_buffered_size(GArrowGPUCUDABufferOutputStream *stream)
+{
+  auto arrow_stream = garrow_gpu_cuda_buffer_output_stream_get_raw(stream);
+  return arrow_stream->num_bytes_buffered();
+}
+
+
+G_END_DECLS
+
+GArrowGPUCUDAContext *
+garrow_gpu_cuda_context_new_raw(std::shared_ptr<arrow::gpu::CudaContext> *arrow_context)
+{
+  return GARROW_GPU_CUDA_CONTEXT(g_object_new(GARROW_GPU_TYPE_CUDA_CONTEXT,
+                                              "context", arrow_context,
+                                              NULL));
+}
+
+std::shared_ptr<arrow::gpu::CudaContext>
+garrow_gpu_cuda_context_get_raw(GArrowGPUCUDAContext *context)
+{
+  if (!context)
+    return nullptr;
+
+  auto priv = GARROW_GPU_CUDA_CONTEXT_GET_PRIVATE(context);
+  return priv->context;
+}
+
+GArrowGPUCUDAIPCMemoryHandle *
+garrow_gpu_cuda_ipc_memory_handle_new_raw(arrow::gpu::CudaIpcMemHandle *arrow_handle)
+{
+  auto handle = g_object_new(GARROW_GPU_TYPE_CUDA_IPC_MEMORY_HANDLE,
+                             "ipc-memory-handle", arrow_handle,
+                             NULL);
+  return GARROW_GPU_CUDA_IPC_MEMORY_HANDLE(handle);
+}
+
+arrow::gpu::CudaIpcMemHandle *
+garrow_gpu_cuda_ipc_memory_handle_get_raw(GArrowGPUCUDAIPCMemoryHandle *handle)
+{
+  if (!handle)
+    return nullptr;
+
+  auto priv = GARROW_GPU_CUDA_IPC_MEMORY_HANDLE_GET_PRIVATE(handle);
+  return priv->ipc_memory_handle;
+}
+
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new_raw(std::shared_ptr<arrow::gpu::CudaBuffer> *arrow_buffer)
+{
+  return GARROW_GPU_CUDA_BUFFER(g_object_new(GARROW_GPU_TYPE_CUDA_BUFFER,
+                                             "buffer", arrow_buffer,
+                                             NULL));
+}
+
+std::shared_ptr<arrow::gpu::CudaBuffer>
+garrow_gpu_cuda_buffer_get_raw(GArrowGPUCUDABuffer *buffer)
+{
+  if (!buffer)
+    return nullptr;
+
+  auto arrow_buffer = garrow_buffer_get_raw(GARROW_BUFFER(buffer));
+  return std::static_pointer_cast<arrow::gpu::CudaBuffer>(arrow_buffer);
+}
+
+GArrowGPUCUDAHostBuffer *
+garrow_gpu_cuda_host_buffer_new_raw(std::shared_ptr<arrow::gpu::CudaHostBuffer> *arrow_buffer)
+{
+  auto buffer = g_object_new(GARROW_GPU_TYPE_CUDA_HOST_BUFFER,
+                             "buffer", arrow_buffer,
+                             NULL);
+  return GARROW_GPU_CUDA_HOST_BUFFER(buffer);
+}
+
+std::shared_ptr<arrow::gpu::CudaHostBuffer>
+garrow_gpu_cuda_host_buffer_get_raw(GArrowGPUCUDAHostBuffer *buffer)
+{
+  if (!buffer)
+    return nullptr;
+
+  auto arrow_buffer = garrow_buffer_get_raw(GARROW_BUFFER(buffer));
+  return std::static_pointer_cast<arrow::gpu::CudaHostBuffer>(arrow_buffer);
+}
+
+GArrowGPUCUDABufferInputStream *
+garrow_gpu_cuda_buffer_input_stream_new_raw(std::shared_ptr<arrow::gpu::CudaBufferReader> *arrow_reader)
+{
+  auto input_stream = g_object_new(GARROW_GPU_TYPE_CUDA_BUFFER_INPUT_STREAM,
+                                   "input-stream", arrow_reader,
+                                   NULL);
+  return GARROW_GPU_CUDA_BUFFER_INPUT_STREAM(input_stream);
+}
+
+std::shared_ptr<arrow::gpu::CudaBufferReader>
+garrow_gpu_cuda_buffer_input_stream_get_raw(GArrowGPUCUDABufferInputStream *input_stream)
+{
+  if (!input_stream)
+    return nullptr;
+
+  auto arrow_reader =
+    garrow_input_stream_get_raw(GARROW_INPUT_STREAM(input_stream));
+  return std::static_pointer_cast<arrow::gpu::CudaBufferReader>(arrow_reader);
+}
+
+GArrowGPUCUDABufferOutputStream *
+garrow_gpu_cuda_buffer_output_stream_new_raw(std::shared_ptr<arrow::gpu::CudaBufferWriter> *arrow_writer)
+{
+  auto output_stream = g_object_new(GARROW_GPU_TYPE_CUDA_BUFFER_OUTPUT_STREAM,
+                                    "output-stream", arrow_writer,
+                                    NULL);
+  return GARROW_GPU_CUDA_BUFFER_OUTPUT_STREAM(output_stream);
+}
+
+std::shared_ptr<arrow::gpu::CudaBufferWriter>
+garrow_gpu_cuda_buffer_output_stream_get_raw(GArrowGPUCUDABufferOutputStream *output_stream)
+{
+  if (!output_stream)
+    return nullptr;
+
+  auto arrow_writer =
+    garrow_output_stream_get_raw(GARROW_OUTPUT_STREAM(output_stream));
+  return std::static_pointer_cast<arrow::gpu::CudaBufferWriter>(arrow_writer);
+}
diff --git a/c_glib/arrow-gpu-glib/cuda.h b/c_glib/arrow-gpu-glib/cuda.h
new file mode 100644
index 0000000..7c615a1
--- /dev/null
+++ b/c_glib/arrow-gpu-glib/cuda.h
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+#include <arrow-glib/arrow-glib.h>
+
+G_BEGIN_DECLS
+
+#define GARROW_GPU_TYPE_CUDA_DEVICE_MANAGER     \
+  (garrow_gpu_cuda_device_manager_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDADeviceManager,
+                         garrow_gpu_cuda_device_manager,
+                         GARROW_GPU,
+                         CUDA_DEVICE_MANAGER,
+                         GObject)
+struct _GArrowGPUCUDADeviceManagerClass
+{
+  GObjectClass parent_class;
+};
+
+#define GARROW_GPU_TYPE_CUDA_CONTEXT (garrow_gpu_cuda_context_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDAContext,
+                         garrow_gpu_cuda_context,
+                         GARROW_GPU,
+                         CUDA_CONTEXT,
+                         GObject)
+struct _GArrowGPUCUDAContextClass
+{
+  GObjectClass parent_class;
+};
+
+#define GARROW_GPU_TYPE_CUDA_BUFFER (garrow_gpu_cuda_buffer_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDABuffer,
+                         garrow_gpu_cuda_buffer,
+                         GARROW_GPU,
+                         CUDA_BUFFER,
+                         GArrowBuffer)
+struct _GArrowGPUCUDABufferClass
+{
+  GArrowBufferClass parent_class;
+};
+
+#define GARROW_GPU_TYPE_CUDA_HOST_BUFFER (garrow_gpu_cuda_host_buffer_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDAHostBuffer,
+                         garrow_gpu_cuda_host_buffer,
+                         GARROW_GPU,
+                         CUDA_HOST_BUFFER,
+                         GArrowMutableBuffer)
+struct _GArrowGPUCUDAHostBufferClass
+{
+  GArrowMutableBufferClass parent_class;
+};
+
+#define GARROW_GPU_TYPE_CUDA_IPC_MEMORY_HANDLE          \
+  (garrow_gpu_cuda_ipc_memory_handle_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDAIPCMemoryHandle,
+                         garrow_gpu_cuda_ipc_memory_handle,
+                         GARROW_GPU,
+                         CUDA_IPC_MEMORY_HANDLE,
+                         GObject)
+struct _GArrowGPUCUDAIPCMemoryHandleClass
+{
+  GObjectClass parent_class;
+};
+
+#define GARROW_GPU_TYPE_CUDA_BUFFER_INPUT_STREAM        \
+  (garrow_gpu_cuda_buffer_input_stream_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDABufferInputStream,
+                         garrow_gpu_cuda_buffer_input_stream,
+                         GARROW_GPU,
+                         CUDA_BUFFER_INPUT_STREAM,
+                         GArrowBufferInputStream)
+struct _GArrowGPUCUDABufferInputStreamClass
+{
+  GArrowBufferInputStreamClass parent_class;
+};
+
+#define GARROW_GPU_TYPE_CUDA_BUFFER_OUTPUT_STREAM               \
+  (garrow_gpu_cuda_buffer_output_stream_get_type())
+G_DECLARE_DERIVABLE_TYPE(GArrowGPUCUDABufferOutputStream,
+                         garrow_gpu_cuda_buffer_output_stream,
+                         GARROW_GPU,
+                         CUDA_BUFFER_OUTPUT_STREAM,
+                         GArrowOutputStream)
+struct _GArrowGPUCUDABufferOutputStreamClass
+{
+  GArrowOutputStreamClass parent_class;
+};
+
+GArrowGPUCUDADeviceManager *
+garrow_gpu_cuda_device_manager_new(GError **error);
+
+GArrowGPUCUDAContext *
+garrow_gpu_cuda_device_manager_get_context(GArrowGPUCUDADeviceManager *manager,
+                                           gint gpu_number,
+                                           GError **error);
+gsize
+garrow_gpu_cuda_device_manager_get_n_devices(GArrowGPUCUDADeviceManager *manager);
+
+gint64
+garrow_gpu_cuda_context_get_allocated_size(GArrowGPUCUDAContext *context);
+
+
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new(GArrowGPUCUDAContext *context,
+                           gint64 size,
+                           GError **error);
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new_ipc(GArrowGPUCUDAContext *context,
+                               GArrowGPUCUDAIPCMemoryHandle *handle,
+                               GError **error);
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new_record_batch(GArrowGPUCUDAContext *context,
+                                        GArrowRecordBatch *record_batch,
+                                        GError **error);
+GBytes *
+garrow_gpu_cuda_buffer_copy_to_host(GArrowGPUCUDABuffer *buffer,
+                                    gint64 position,
+                                    gint64 size,
+                                    GError **error);
+gboolean
+garrow_gpu_cuda_buffer_copy_from_host(GArrowGPUCUDABuffer *buffer,
+                                      const guint8 *data,
+                                      gint64 size,
+                                      GError **error);
+GArrowGPUCUDAIPCMemoryHandle *
+garrow_gpu_cuda_buffer_export(GArrowGPUCUDABuffer *buffer,
+                              GError **error);
+GArrowGPUCUDAContext *
+garrow_gpu_cuda_buffer_get_context(GArrowGPUCUDABuffer *buffer);
+GArrowRecordBatch *
+garrow_gpu_cuda_buffer_read_record_batch(GArrowGPUCUDABuffer *buffer,
+                                         GArrowSchema *schema,
+                                         GError **error);
+
+
+GArrowGPUCUDAHostBuffer *
+garrow_gpu_cuda_host_buffer_new(gint64 size, GError **error);
+
+GArrowGPUCUDAIPCMemoryHandle *
+garrow_gpu_cuda_ipc_memory_handle_new(const guint8 *data,
+                                      gsize size,
+                                      GError **error);
+
+GArrowBuffer *
+garrow_gpu_cuda_ipc_memory_handle_serialize(GArrowGPUCUDAIPCMemoryHandle *handle,
+                                            GError **error);
+
+GArrowGPUCUDABufferInputStream *
+garrow_gpu_cuda_buffer_input_stream_new(GArrowGPUCUDABuffer *buffer);
+
+GArrowGPUCUDABufferOutputStream *
+garrow_gpu_cuda_buffer_output_stream_new(GArrowGPUCUDABuffer *buffer);
+
+gboolean
+garrow_gpu_cuda_buffer_output_stream_set_buffer_size(GArrowGPUCUDABufferOutputStream *stream,
+                                                     gint64 size,
+                                                     GError **error);
+gint64
+garrow_gpu_cuda_buffer_output_stream_get_buffer_size(GArrowGPUCUDABufferOutputStream *stream);
+gint64
+garrow_gpu_cuda_buffer_output_stream_get_buffered_size(GArrowGPUCUDABufferOutputStream *stream);
+
+G_END_DECLS
diff --git a/c_glib/arrow-gpu-glib/cuda.hpp b/c_glib/arrow-gpu-glib/cuda.hpp
new file mode 100644
index 0000000..3eeff8b
--- /dev/null
+++ b/c_glib/arrow-gpu-glib/cuda.hpp
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+#include <arrow/gpu/cuda_api.h>
+
+#include <arrow-gpu-glib/cuda.h>
+
+GArrowGPUCUDAContext *
+garrow_gpu_cuda_context_new_raw(std::shared_ptr<arrow::gpu::CudaContext> *arrow_context);
+std::shared_ptr<arrow::gpu::CudaContext>
+garrow_gpu_cuda_context_get_raw(GArrowGPUCUDAContext *context);
+
+GArrowGPUCUDAIPCMemoryHandle *
+garrow_gpu_cuda_ipc_memory_handle_new_raw(arrow::gpu::CudaIpcMemHandle *arrow_handle);
+arrow::gpu::CudaIpcMemHandle *
+garrow_gpu_cuda_ipc_memory_handle_get_raw(GArrowGPUCUDAIPCMemoryHandle *handle);
+
+GArrowGPUCUDABuffer *
+garrow_gpu_cuda_buffer_new_raw(std::shared_ptr<arrow::gpu::CudaBuffer> *arrow_buffer);
+std::shared_ptr<arrow::gpu::CudaBuffer>
+garrow_gpu_cuda_buffer_get_raw(GArrowGPUCUDABuffer *buffer);
+
+GArrowGPUCUDAHostBuffer *
+garrow_gpu_cuda_host_buffer_new_raw(std::shared_ptr<arrow::gpu::CudaHostBuffer> *arrow_buffer);
+std::shared_ptr<arrow::gpu::CudaHostBuffer>
+garrow_gpu_cuda_host_buffer_get_raw(GArrowGPUCUDAHostBuffer *buffer);
+
+GArrowGPUCUDABufferInputStream *
+garrow_gpu_cuda_buffer_input_stream_new_raw(std::shared_ptr<arrow::gpu::CudaBufferReader> *arrow_reader);
+std::shared_ptr<arrow::gpu::CudaBufferReader>
+garrow_gpu_cuda_buffer_input_stream_get_raw(GArrowGPUCUDABufferInputStream *input_stream);
+
+GArrowGPUCUDABufferOutputStream *
+garrow_gpu_cuda_buffer_output_stream_new_raw(std::shared_ptr<arrow::gpu::CudaBufferWriter> *arrow_writer);
+std::shared_ptr<arrow::gpu::CudaBufferWriter>
+garrow_gpu_cuda_buffer_output_stream_get_raw(GArrowGPUCUDABufferOutputStream *output_stream);
diff --git a/c_glib/arrow-gpu-glib/meson.build b/c_glib/arrow-gpu-glib/meson.build
new file mode 100644
index 0000000..00c7f07
--- /dev/null
+++ b/c_glib/arrow-gpu-glib/meson.build
@@ -0,0 +1,80 @@
+# -*- indent-tabs-mode: nil -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+sources = files(
+  'cuda.cpp',
+)
+
+c_headers = files(
+  'arrow-gpu-glib.h',
+  'cuda.h',
+)
+
+cpp_headers = files(
+  'arrow-gpu-glib.hpp',
+  'cuda.hpp',
+)
+
+headers = c_headers + cpp_headers
+install_headers(headers, subdir: 'arrow-gpu-glib')
+
+
+dependencies = [
+  arrow_gpu_dependency,
+  libarrow_glib_dependency,
+]
+libarrow_gpu_glib = library('arrow-gpu-glib',
+                            sources: sources,
+                            install: true,
+                            dependencies: dependencies,
+                            include_directories: [
+                              root_inc,
+                            ],
+                            soversion: so_version,
+                            version: library_version)
+libarrow_gpu_glib_dependency = declare_dependency(link_with: libarrow_gpu_glib,
+                                                  include_directories: [
+                                                    root_inc,
+                                                  ],
+                                                  dependencies: dependencies)
+
+pkgconfig.generate(filebase: 'arrow-gpu-glib',
+                   name: 'Apache Arrow GPU GLib',
+                   description: 'C API for Apache Arrow GPU based on GLib',
+                   version: version,
+                   requires: ['arrow-glib', 'arrow-gpu'],
+                   libraries: [libarrow_gpu_glib],
+                   subdirs: ['arrow-gpu-glib'])
+
+gnome.generate_gir(libarrow_gpu_glib,
+                   dependencies: arrow_glib_gir_dependency,
+                   sources: sources + c_headers,
+                   namespace: 'ArrowGPU',
+                   nsversion: api_version,
+                   identifier_prefix: 'GArrowGPU',
+                   symbol_prefix: 'garrow_gpu',
+                   export_packages: 'arrow-gpu-glib',
+                   includes: [
+                     'Arrow-1.0',
+                   ],
+                   install: true,
+                   extra_args: [
+                     '--warn-all',
+                     '--include-uninstalled=./arrow-glib/Arrow-1.0.gir',
+                   ])
diff --git a/c_glib/configure.ac b/c_glib/configure.ac
index 5db4352..c6fa019 100644
--- a/c_glib/configure.ac
+++ b/c_glib/configure.ac
@@ -77,18 +77,34 @@ AC_ARG_WITH(arrow-cpp-build-dir,
   [GARROW_ARROW_CPP_BUILD_DIR=""])
 if test "x$GARROW_ARROW_CPP_BUILD_DIR" = "x"; then
   PKG_CHECK_MODULES([ARROW], [arrow arrow-compute])
+  PKG_CHECK_MODULES([ARROW_GPU],
+                    [arrow-gpu],
+                    [HAVE_ARROW_GPU=yes],
+                    [HAVE_ARROW_GPU=no])
 else
   ARROW_INCLUDE_DIR="\$(abs_top_srcdir)/../cpp/src"
   ARROW_LIB_DIR="${GARROW_ARROW_CPP_BUILD_DIR}/${GARROW_ARROW_CPP_BUILD_TYPE}"
 
   ARROW_CFLAGS="-I${ARROW_INCLUDE_DIR}"
-
   ARROW_LIBS="-L${ARROW_LIB_DIR} -larrow"
-
-  AC_SUBST(ARROW_LIB_DIR)
-
   AC_SUBST(ARROW_CFLAGS)
   AC_SUBST(ARROW_LIBS)
+
+  ARROW_GPU_CFLAGS=""
+  if test -f "${GARROW_ARROW_CPP_BUILD_DIR}/src/arrow/gpu/arrow-gpu.pc"; then
+    HAVE_ARROW_GPU=yes
+    ARROW_GPU_LIBS="-larrow_gpu"
+  else
+    HAVE_ARROW_GPU=no
+    ARROW_GPU_LIBS=""
+  fi
+  AC_SUBST(ARROW_GPU_CFLAGS)
+  AC_SUBST(ARROW_GPU_LIBS)
+fi
+
+AM_CONDITIONAL([HAVE_ARROW_GPU], [test "$HAVE_ARROW_GPU" = "yes"])
+if test "$HAVE_ARROW_GPU" = "yes"; then
+  AC_DEFINE(HAVE_ARROW_GPU, [1], [Define to 1 if Apache Arrow supports GPU.])
 fi
 
 exampledir="\$(datadir)/arrow-glib/example"
@@ -98,6 +114,8 @@ AC_CONFIG_FILES([
   Makefile
   arrow-glib/Makefile
   arrow-glib/arrow-glib.pc
+  arrow-gpu-glib/Makefile
+  arrow-gpu-glib/arrow-gpu-glib.pc
   doc/Makefile
   doc/reference/Makefile
   doc/reference/xml/Makefile
diff --git a/c_glib/doc/Makefile.am b/c_glib/doc/Makefile.am
index 85c1d51..1d491ab 100644
--- a/c_glib/doc/Makefile.am
+++ b/c_glib/doc/Makefile.am
@@ -16,4 +16,4 @@
 # under the License.
 
 SUBDIRS =                                       \
-        reference
+	reference
diff --git a/c_glib/doc/reference/Makefile.am b/c_glib/doc/reference/Makefile.am
index 45b11f0..896aff5 100644
--- a/c_glib/doc/reference/Makefile.am
+++ b/c_glib/doc/reference/Makefile.am
@@ -51,6 +51,17 @@ AM_CFLAGS =					\
 GTKDOC_LIBS =						\
 	$(top_builddir)/arrow-glib/libarrow-glib.la
 
+if HAVE_ARROW_GPU
+DOC_SOURCE_DIR +=				\
+	$(top_srcdir)/arrow-gpu-glib
+HFILE_GLOB +=					\
+	$(top_srcdir)/arrow-gpu-glib/*.h
+CFILE_GLOB +=					\
+	$(top_srcdir)/arrow-gpu-glib/*.cpp
+GTKDOC_LIBS +=							\
+	$(top_builddir)/arrow-gpu-glib/libarrow-gpu-glib.la
+endif
+
 include $(srcdir)/gtk-doc.make
 
 CLEANFILES +=					\
diff --git a/c_glib/doc/reference/arrow-glib-docs.sgml b/c_glib/doc/reference/arrow-glib-docs.sgml
index a504ef1..e267ea2 100644
--- a/c_glib/doc/reference/arrow-glib-docs.sgml
+++ b/c_glib/doc/reference/arrow-glib-docs.sgml
@@ -125,6 +125,16 @@
     </chapter>
   </part>
 
+  <!-- TODO
+  <part id="gpu">
+    <title>GPU</title>
+    <chapter id="cuda">
+      <title>CUDA</title>
+      <xi:include href="xml/cuda.xml"/>
+    </chapter>
+  </part>
+  -->
+
   <chapter id="object-tree">
     <title>Object Hierarchy</title>
     <xi:include href="xml/tree_index.sgml"/>
diff --git a/c_glib/doc/reference/meson.build b/c_glib/doc/reference/meson.build
index 08936da..4c9552e 100644
--- a/c_glib/doc/reference/meson.build
+++ b/c_glib/doc/reference/meson.build
@@ -32,13 +32,26 @@ glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
 glib_doc_path = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
 doc_path = join_paths(data_dir, meson.project_name(), 'gtk-doc', 'html')
 
+source_directories = [
+  join_paths(meson.source_root(), 'arrow-glib'),
+  join_paths(meson.build_root(), 'arrow-glib'),
+]
+dependencies = [
+  libarrow_glib_dependency,
+]
+if arrow_gpu_dependency.found()
+  source_directories += [
+    join_paths(meson.source_root(), 'arrow-gpu-glib'),
+    join_paths(meson.build_root(), 'arrow-gpu-glib'),
+  ]
+  dependencies += [
+    libarrow_gpu_glib_dependency,
+  ]
+endif
 gnome.gtkdoc(meson.project_name(),
              main_xml: meson.project_name() + '-docs.sgml',
-             src_dir: [
-               join_paths(meson.source_root(), 'arrow-glib'),
-               join_paths(meson.build_root(), 'arrow-glib'),
-             ],
-             dependencies: libarrow_glib_dependency,
+             src_dir: source_directories,
+             dependencies: dependencies,
              gobject_typesfile: meson.project_name() + '.types',
              scan_args: [
                '--rebuild-types',
diff --git a/c_glib/meson.build b/c_glib/meson.build
index 1fa64ba..9fe1b8c 100644
--- a/c_glib/meson.build
+++ b/c_glib/meson.build
@@ -49,6 +49,10 @@ pkgconfig = import('pkgconfig')
 root_inc = include_directories('.')
 
 subdir('arrow-glib')
+arrow_gpu_dependency = dependency('arrow-gpu', required: false)
+if arrow_gpu_dependency.found()
+  subdir('arrow-gpu-glib')
+endif
 subdir('example')
 
 if get_option('enable_gtk_doc')
@@ -58,4 +62,7 @@ endif
 run_test = find_program('test/run-test.sh')
 test('unit test',
      run_test,
-     env: ['ARROW_GLIB_TYPELIB_DIR=@0@/arrow-glib'.format(meson.build_root())])
+     env: [
+       'ARROW_GLIB_TYPELIB_DIR=@0@/arrow-glib'.format(meson.build_root()),
+       'ARROW_GPU_GLIB_TYPELIB_DIR=@0@/arrow-gpu-glib'.format(meson.build_root()),
+     ])
diff --git a/c_glib/test/run-test.rb b/c_glib/test/run-test.rb
index 3451bd2..392c56f 100755
--- a/c_glib/test/run-test.rb
+++ b/c_glib/test/run-test.rb
@@ -37,6 +37,12 @@ module Arrow
   end
 end
 
+begin
+  ArrowGPU = GI.load("ArrowGPU")
+rescue GObjectIntrospection::RepositoryError::TypelibNotFound
+end
+
+require "rbconfig"
 require "tempfile"
 require_relative "helper/buildable"
 require_relative "helper/omittable"
diff --git a/c_glib/test/run-test.sh b/c_glib/test/run-test.sh
index 19ccf07..d563e85 100755
--- a/c_glib/test/run-test.sh
+++ b/c_glib/test/run-test.sh
@@ -20,27 +20,34 @@
 test_dir="$(cd $(dirname $0); pwd)"
 build_dir="$(cd .; pwd)"
 
-arrow_glib_build_dir="${build_dir}/arrow-glib/"
-libtool_dir="${arrow_glib_build_dir}/.libs"
-if [ -d "${libtool_dir}" ]; then
-  LD_LIBRARY_PATH="${libtool_dir}:${LD_LIBRARY_PATH}"
-else
-  if [ -d "${arrow_glib_build_dir}" ]; then
-    LD_LIBRARY_PATH="${arrow_glib_build_dir}:${LD_LIBRARY_PATH}"
+modules="arrow-glib arrow-gpu-glib"
+
+for module in ${modules}; do
+  module_build_dir="${build_dir}/${module}"
+  libtool_dir="${module_build_dir}/.libs"
+  if [ -d "${libtool_dir}" ]; then
+    LD_LIBRARY_PATH="${libtool_dir}:${LD_LIBRARY_PATH}"
+  else
+    if [ -d "${module_build_dir}" ]; then
+      LD_LIBRARY_PATH="${module_build_dir}:${LD_LIBRARY_PATH}"
+    fi
   fi
-fi
+done
 
 if [ -f "Makefile" -a "${NO_MAKE}" != "yes" ]; then
   make -j8 > /dev/null || exit $?
 fi
 
-arrow_glib_typelib_dir="${ARROW_GLIB_TYPELIB_DIR}"
-if [ -z "${arrow_glib_typelib_dir}" ]; then
-  arrow_glib_typelib_dir="${build_dir}/arrow-glib"
-fi
+for module in ${modules}; do
+  MODULE_TYPELIB_DIR_VAR_NAME="$(echo ${module} | tr a-z- A-Z_)_TYPELIB_DIR"
+  module_typelib_dir=$(eval "echo \${${MODULE_TYPELIB_DIR_VAR_NAME}}")
+  if [ -z "${module_typelib_dir}" ]; then
+    module_typelib_dir="${build_dir}/${module}"
+  fi
 
-if [ -d "${arrow_glib_typelib_dir}" ]; then
-  GI_TYPELIB_PATH="${arrow_glib_typelib_dir}:${GI_TYPELIB_PATH}"
-fi
+  if [ -d "${module_typelib_dir}" ]; then
+    GI_TYPELIB_PATH="${module_typelib_dir}:${GI_TYPELIB_PATH}"
+  fi
+done
 
 ${GDB} ruby ${test_dir}/run-test.rb "$@"
diff --git a/c_glib/test/test-gpu-cuda.rb b/c_glib/test/test-gpu-cuda.rb
new file mode 100644
index 0000000..c710ef2
--- /dev/null
+++ b/c_glib/test/test-gpu-cuda.rb
@@ -0,0 +1,144 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+class TestGPUCUDA < Test::Unit::TestCase
+  include Helper::Buildable
+
+  def setup
+    omit("Arrow GPU is required") unless defined?(::ArrowGPU)
+    @manager = ArrowGPU::CUDADeviceManager.new
+    omit("At least one GPU is required") if @manager.n_devices.zero?
+    @context = @manager.get_context(0)
+  end
+
+  sub_test_case("Context") do
+    def test_allocated_size
+      allocated_size_before = @context.allocated_size
+      size = 128
+      buffer = ArrowGPU::CUDABuffer.new(@context, size)
+      assert_equal(size,
+                   @context.allocated_size - allocated_size_before)
+    end
+  end
+
+  sub_test_case("Buffer") do
+    def setup
+      super
+      @buffer = ArrowGPU::CUDABuffer.new(@context, 128)
+    end
+
+    def test_copy
+      @buffer.copy_from_host("Hello World")
+      assert_equal("llo W", @buffer.copy_to_host(2, 5).to_s)
+    end
+
+    def test_export
+      @buffer.copy_from_host("Hello World")
+      handle = @buffer.export
+      serialized_handle = handle.serialize.data
+      Tempfile.open("arrow-gpu-cuda-export") do |output|
+        pid = spawn(RbConfig.ruby, "-e", <<-SCRIPT)
+require "gi"
+
+Gio = GI.load("Gio")
+Arrow = GI.load("Arrow")
+ArrowGPU = GI.load("ArrowGPU")
+
+manager = ArrowGPU::CUDADeviceManager.new
+context = manager.get_context(0)
+serialized_handle = #{serialized_handle.to_s.dump}
+handle = ArrowGPU::CUDAIPCMemoryHandle.new(serialized_handle)
+buffer = ArrowGPU::CUDABuffer.new(context, handle)
+File.open(#{output.path.dump}, "w") do |output|
+  output.print(buffer.copy_to_host(0, 6).to_s)
+end
+        SCRIPT
+        Process.waitpid(pid)
+        assert_equal("Hello ", output.read)
+      end
+    end
+
+    def test_context
+      assert_equal(@context.allocated_size,
+                   @buffer.context.allocated_size)
+    end
+
+    def test_record_batch
+      field = Arrow::Field.new("enabled", Arrow::BooleanDataType.new)
+      schema = Arrow::Schema.new([field])
+      columns = [
+        build_boolean_array([true]),
+      ]
+      cpu_record_batch = Arrow::RecordBatch.new(schema, 1, columns)
+
+      buffer = ArrowGPU::CUDABuffer.new(@context, cpu_record_batch)
+      gpu_record_batch = buffer.read_record_batch(schema)
+      assert_equal(cpu_record_batch.n_rows,
+                   gpu_record_batch.n_rows)
+    end
+  end
+
+  sub_test_case("HostBuffer") do
+    def test_new
+      buffer = ArrowGPU::CUDAHostBuffer.new(128)
+      assert_equal(128, buffer.size)
+    end
+  end
+
+  sub_test_case("BufferInputStream") do
+    def test_new
+      buffer = ArrowGPU::CUDABuffer.new(@context, 128)
+      buffer.copy_from_host("Hello World")
+      stream = ArrowGPU::CUDABufferInputStream.new(buffer)
+      begin
+        assert_equal("Hello Worl", stream.read(5).copy_to_host(0, 10).to_s)
+      ensure
+        stream.close
+      end
+    end
+  end
+
+  sub_test_case("BufferOutputStream") do
+    def setup
+      super
+      @buffer = ArrowGPU::CUDABuffer.new(@context, 128)
+      @buffer.copy_from_host("\x00" * @buffer.size)
+      @stream = ArrowGPU::CUDABufferOutputStream.new(@buffer)
+    end
+
+    def cleanup
+      super
+      @stream.close
+    end
+
+    def test_new
+      @stream.write("Hello World")
+      assert_equal("Hello World", @buffer.copy_to_host(0, 11).to_s)
+    end
+
+    def test_buffer
+      assert_equal(0, @stream.buffer_size)
+      @stream.buffer_size = 5
+      assert_equal(5, @stream.buffer_size)
+      @stream.write("Hell")
+      assert_equal(4, @stream.buffered_size)
+      assert_equal("\x00" * 5, @buffer.copy_to_host(0, 5).to_s)
+      @stream.write("o")
+      assert_equal("Hello", @buffer.copy_to_host(0, 5).to_s)
+    end
+  end
+end

-- 
To stop receiving notification emails like this one, please contact
['"commits@arrow.apache.org" <commits@arrow.apache.org>'].

Mime
View raw message